🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

OS

OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

UNIX

UNIXとは、AT&Tのベル研究所で開発されたコンピューター用のマルチユーザー・マルチタスクのオペレーションシステム(OS)です。政府や教育機関や研究所で広範囲に採用されています。

Q&A

解決済

3回答

3804閲覧

C言語 ファイル中の単語数、バイト数の計算について

NM4869

総合スコア9

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

OS

OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

UNIX

UNIXとは、AT&Tのベル研究所で開発されたコンピューター用のマルチユーザー・マルチタスクのオペレーションシステム(OS)です。政府や教育機関や研究所で広範囲に採用されています。

0グッド

0クリップ

投稿2019/10/29 08:20

C言語を使いUNIXやLINUXのls, cd, wcのようなコマンドをじぶんで作成しようとしています。現在やっているのは wc file のようなコマンドを実行した時に 3 3 25 という結果を返す関数を作ろうとしています。返り値の数字は左から行、単語数、バイト数です。以下のコードが自分で作成しているものですが、最初の行数以外が現状は正しい結果を返していません。

試したこととしては単語数の計算についてはスペース、改行、タブを確認し数えようとしていますが、結果は常に0となってしまいます。以下の写真が実行例です。

バイト数の計算についてはfseek関数を使いファイル中のバイト数をしゅとくしようとしました。

イメージ説明 
こちらがファイルの中身です。
イメージ説明

ファイル中の単語数の計算、バイト数の計算についてアドバイスをいただけますと幸いです。
宜しくお願いします。

C言語

1int smallsh_wc(char **args){ 2 // Declaring the file pointer 3 FILE *fp; 4 char buffer[2000]; 5 int line = 0; //int word = 0; 6 int count = 0; 7 8 // check file is open or not 9 if((fp = fopen(args[1], "r")) == NULL){ 10 printf("can not open file. %s\n", args[1]); 11 exit(2); 12 } 13 14 // fgets read 1 line by stream 15 /* count the line in the file */ 16 while(fgets(buffer, 2000, fp) != NULL){ 17 line++; 18 } 19 printf("%d ", line); 20 21 /* count the word in the file */ 22 while(fgets(buffer, 2000, fp) != NULL){ 23 if(fgets(buffer, 2000, fp) == ' '){ 24 count++; 25 } 26 if(fgets(buffer, 2000, fp) == '\n'){ 27 count++; 28 } 29 if(fgets(buffer, 2000, fp) == "\t"){ 30 count++; 31 } 32 } 33 printf("%d ", count); 34 35 fseek(fp, SEEK_SET, SEEK_END); 36 printf("%d \n", args[1], ftell(fp)); 37 38 fclose(fp); 39 return 1; 40}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

バイト数とのことなので、

if((fp = fopen(args[1], "r")) == NULL){

ここでのオープンは、"r" で無く、"rb" としましょう。(バイナリRead)

あとは、

C

1 int totalCount = 0; /* 総バイト数 */ 2 int wordCount = 0; /* 単語? 数 */ 3 int lineCount = 0; /* 行数 */ 4 int lastIsSpace = 1; /* 直前の文字の種類 ... 空白文字で0以外 */ 5 int ch = fgetc(fp); /* 最初の文字読み込み */ 6 while (EOF != ch) { 7 totalCount++; 8 if (isspace(ch)) { 9 if (!lastIsSpace) wordCount++; 10 if (ch == '\n') lineCount++; 11 lastIsSpace = 1; 12 } else { 13 lastIsSpace = 0; 14 } 15 ch = fgetc(fp); 16 } 17

辺りでしょうか?

細かなチェックはしてません。

投稿2019/10/29 13:43

pepperleaf

総合スコア6385

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pepperleaf

2019/11/01 11:36

ファイルの最後が改行で終わっていない場合、ちょっと問題あり。 対応はできるけど、特にコメントも無いようなので、課題として。
guest

0

ファイルを1バイトずつファイル終わりまで読みながら、全部の数をカウントするのがいいです。

・バイト数を+1
・改行文字なら行数を+1
・空白文字か非空白文字かを判断し、空白文字から非空白文字に切り替わる時点で、単語数を+1
・ファイルの最初と最後の部分はよく考える。

投稿2019/10/29 09:49

otn

総合スコア85890

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

printf("%d ", line);の直前までの時点でファイルの内容を全て読み込んだでしょうから,
以降のfgets(buffer, 2000, fp)は全て失敗しているのではないでしょうか.

また,ftell()の返す値はテキストモードのファイルでは未規定とのことなので,ファイルサイズの取得には使えません.

{行数,単語数,ファイルサイズ}という各要素を個別に求めるのでなく,一度にやれば良いかと思います.
1行読込む毎に

  • 行数をインクリメント
  • 読み込めた行の内容を調べて単語数を加算
  • 読み込めた行の内容を調べてファイルサイズを加算

という感じで.

投稿2019/10/29 08:32

編集2019/10/29 08:39
fana

総合スコア11987

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問