• 締切済み

英文字の出現頻度

英語で書かれているファイルを読み込んで英文字の出現頻度を調べるプログラムを作ったのですが、ところどころ正確な数が表示されません。どなたか教えてもらえませんか?欲を言えばスペースや改行もカウントできれば良いのですが・・・よろしくお願いしますm(_ _)m #include <stdio.h> #define N 500 int main(int argc, char *argv[]) { int c,i=0; int X[N]; FILE *fp; char ch[N]; if( argc != 2) { printf("使い方:コマンド名に続きファイル名を入れてください\n"); return -1; } fp = fopen( argv[1],"rb"); while(fgets(ch,500,fp) != NULL ) { printf("%sファイルにおけるアルファベットの出現頻度\n",argv[1],ch); { while ((c = getc(fp)) != EOF) if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') X[c]++; { for (c = 'a'; c <= 'z'; c++) printf("%c:%d\n",c, X[c]); printf("\n"); for (c = 'A'; c <= 'Z'; c++) printf("%c:%d\n",c, X[c] ); printf("\n"); } } } fclose(fp); return 0; }

みんなの回答

  • mac_res
  • ベストアンサー率36% (568/1571)
回答No.3

#include <stdio.h> #define N 128 int main(int argc, char *argv[]) { int c, i; int X[N]; FILE *fp; if (argc != 2) { printf("使い方:コマンド名に続きファイル名を入れてください\n"); return -1; } for (i = 0; i < N; i++) { X[i] = 0; } fp = fopen(argv[1], "r"); while ((c = getc(fp)) != EOF) if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == ' ') || ( c == '\t') || (c == '\n')) X[c]++; printf("%sファイルにおけるアルファベットの出現頻度\n", argv[1]); for (c = 'a'; c <= 'z'; c++) printf("%c:%d\n", c, X[c]); printf("\n"); for (c = 'A'; c <= 'Z'; c++) printf("%c:%d\n", c, X[c]); printf("\n"); printf("空白:%d\n", X[' ']); printf("TAB:%d\n", X['\t']); printf("改行:%d\n", X['\n']); fclose(fp); return 0; }

  • harlan
  • ベストアンサー率77% (234/303)
回答No.2

No.1です。間違いがありました。 誤 スペースは、c==" " または、c==0x20、改行は、c=="\n" とすれば、検出できます。 正 スペースは、c==' ' または、c==0x20、改行は、c=='\n' とすれば、検出できます。

  • harlan
  • ベストアンサー率77% (234/303)
回答No.1

> fp = fopen( argv[1],"rb"); バイナリモードでファイルをオープンしていますが、今回のような目的では、テキストモードで扱って下さい。 テキストモードなら、テキストファイル中の改行コード「\r\n」が自動的に1個の「\n」に変換されますので 改行を数える時にも、処理が簡単になります。 また、fopenの返す値を評価して、ファイルがオープンできなかった場合のエラー処理を行うのが一般的です。 if((fp = fopen(argv[1],"r"))==NULL) {  エラー処理 } > printf("%sファイルにおけるアルファベットの出現頻度\n",argv[1],ch); > { 2つ目の引数、ch は不要です。 また、printf文のすぐ下に { が入っているのはおかしいです。コンパイル時にエラーは出ませんでしたか? > while(fgets(ch,500,fp) != NULL ) 最初に、ch[ ]に、500-1文字または改行まで読み込んでいますが、その後、ch[]は使われていません。 これでは、ファイル先頭の500-1文字、または1行分がカウントできていません。この処理は何のために あるのでしょうか? 2つ目のwhileループで、ch[ ]の中身を評価、カウントするのかと思いましたが、2つ目でもファイルから直接 読み込んでいるので、このループの意味がわかりません。 > if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') X[c]++; X[N]を初期化しないで使っています。値を代入するまえに、ゼロクリアして下さい。 > 欲を言えばスペースや改行もカウントできれば良いのですが スペースは、c==" " または、c==0x20、改行は、c=="\n" とすれば、検出できます。 文字コードを配列の添え字にそのまま使ってしまうというのは、ユニークな考え方だと思いますが 絶対に使われない分までメモリを確保しなければならないというのは、個人的には、もったいない気がします。 しかし、その分処理が簡潔に記述できているので、ここではその良し悪しについては議論しません。

関連するQ&A