• 締切済み

英文字の出現頻度

英語で書かれているファイルを読み込んで英文字の出現頻度を調べるプログラムを作ったのですが、ところどころ正確な数が表示されません。どなたか教えてもらえませんか?欲を言えばスペースや改行もカウントできれば良いのですが・・・よろしくお願いします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

  • C言語の質問です

    下記のプログラムはテキストファイルを読み込み、AからZまでの文字(小文字、大文字は区別しない)がそれぞれ何回 現れたかを数えるプログラムです。 #include <stdio.h> #include <stdlib.h> #include <ctype.h> int count[26]; int main(int argc, char *argv[]) { FILE *fp; char ch; int i; /* ファイル名の指定を調べる */ if(argc!=2) { printf("ファイル名の指定がありません\n"); exit(1); } if((fp = fopen(argv[1], "r"))==NULL) { printf("ファイルを開くことができません\n"); exit(1); } while((ch=fgetc(fp))!=EOF) { ch = toupper(ch); if(ch>='A' && ch<='Z') count[ch-'A']++; } for(i=0; i<26; i++) printf("%c は %d 回出現\n", i+'A', count[i]); fclose(fp); return 0; } 1)int count[26]; で、なぜ26なのかが分かりません。 2)count[ch-'A']++; はどういう動作をするのか詳しく教えてほしいです。 3)よって、for文がどういう動作で表示しているのかが分かりません。 未熟者の私ですが、どなたか教えていただけないでしょうか?

  • 探索アルゴリズム

    テキストファイルを読み込んで、該当する文字列を含む行を表示するというプログラムを作りたいのです。ファイルを読み込むことはできるのですが、該当する文字列を含む行を表示するやり方がわかりません。どなたか助けてもらえないでしょうか? 一応私が作ってみたプログラムはこんな感じになったんですけど・・・ #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) {  FILE *fp;  char ch;  if( argc != 3)  {  printf(" 使用法 : <プログラム名> <ファイル名> <文字> \n");  return -1;  }  if((fp = fopen(argv[1],"r")) == NULL)  {  printf("ファイルを開くことができません\n");  return -1;  }  while(( ch = fgetc(fp)) != EOF)  if(ch == *argv[2])  {  printf("%cが見つかりました\n",ch);  break;  }  fclose(fp);  return 0; }

  • プログラムのソート

    "英語のテキストを読みこんで、出現する文字数のカウントをする"というプログラムを作成しました。このプログラムの出力を出現頻度順(大きい順)に並べ換えたいのですが、どの位置からソートを開始して、関数をどうすればいいのかがよく解りません。どなたかご教授下さい。 ↓取り敢えず、出来たプログラムを載せておきます。 #include<stdio.h> int main(int argc,char *argv[]) { int ch; // 小文字用 int CH; // 大文字用 int a; // str[CH]+str[ch] FILE *fp; int str[128]={0}; fp = fopen(argv[1],"r"); if(fp == NULL){ printf("I can't find it. You need to write a file name ! \n"); exit(1); }else{ printf("指定されたファイル '%s' 内の各文字の個数は以下の通り. \n",argv[1]); while((ch=fgetc(fp)) != EOF){ if(ch < 128) str[ch]++; } for(ch=0; ch<128; ch++){ if(str[ch] != 0){ if(ch>=65 && ch<=90 || ch>=97 && ch<=122){ // A~Z, a~z if(ch>=97 && ch<=122){ // a~z CH = toupper(ch); // 小文字を大文字に a = str[CH]+str[ch]; printf(" (%c)%5d (%c)%5d (%c+%c)%5d \n",CH,str[CH],ch,str[ch],CH,ch,a); } } } } fclose(fp); } return 0; }

  • 友達から頼まれましたが。。。

    問題もよくわからず困っています。 問題:ファイル名を指定し~~の出現頻度を表示する。 大文字小文字は区別無し。 #include<stdio.h> int main(int argc,char *argv[]) { int i,c,freq[26]={0}; FILE *fp; if(argc<(1){ put("入力ファイルがないよっ!!"); goto(2); } argv++; if((fp=fopen((3),"r"))==NULL){ printf("ファイル%sをオープンできません。\n",(3)); goto(2); } while((c=fgetc(fp))!=EOF{ if(c(4)'a'(5)c(6)'z') freq[(7)]++; else if(c(4)'A'(5)c(6)'Z') freq[(8)]++; } fclose(fp); for(i=0;i<26;i++) printf("%cまたは%c%5d\n",(9)+i,(10)+i,freq[i]); RET:return(0); } かっこには何が入るのでしょうか?そしてこれはどんな問題なのでしょうか? 申し訳ないですがお願いします。

  • ファイルの出力

    コマンドラインで指定したファイルの内容を一行ずつ表示するプログラムです。一行表示するごとに次の行も表示するか尋ねます。 #include<stdio.h> #include<stdlib.h> #include<ctype.h> int main(int argc, char *argv[]) {  FILE *fp;  char str[80];  char ch;  if (argc != 2){   printf("コマンドライン引数が違います\n");   exit(1);  }  if ((fp = fopen(argv[1],"r")) == NULL){   printf("ファイルが開けません");   exit(1);  }  while(!feof(fp)){   fgets(str, 79, fp);   if (!feof(fp)) printf("%s",str);   printf("追加しますか?(y/n)");   gets(str);   if ( toupper(*str) == 'N') break;   printf("\n");  }     if (fclose(fp) == EOF){   printf("ファイルを閉じれません\n");   exit(1);  }  return 0; } while文の   gets(str);  if ( toupper(*str) == 'N') break; この部分を  ch = getchar();  if ( toupper(ch) == 'N') break; でやると上手く実行できないのですが、なぜでずか?

  • おしえて

    #include <stdio.h> #include <stdlib.h> int a[30000][6]; int main(int argc, char *argv[]) { FILE *fp; int c,n,i,j; if ((fp = fopen(argv[1], "r")) == NULL) { printf("File Open Error.\n"); exit(1); } for(i=0;i<30000;i++){ for(j=0;j<6;j++){ c = fscanf(fp, "%d", &n); if (c) { a[i][j]=c; printf("%d ",a[i][j]); } } printf("\n"); } fclose(fp); return 0; } このプログラムを書きましたna.txtのファイルが以下のようなとき 1 2 3 4 5 6 3 4 5 6 7 8 のとき先頭の1しか配列に格納できません。どうしても順番にa[0][0~5]=1~6と入れたいです。どうしてもわかりません。おしえてください!!

  • 英小文字個数のカウントについて(C)

    はじめまして。 勉強中の初心者です。 みなさんの質問に対し、すぐに詳しい方々が親切な回答をされている為、 よく閲覧させていただいております。 #include <stdio.h> int main(int argc, char *argv[]) { char countmoji; int count[26], i; if ((argc == 1)||(argc > 2)) { printf("Usage : ALFSCH <strring>\n\n"); exit(0); } for (countmoji = 0x61; countmoji <= 0x7a; countmoji++) { count[countmoji] = 0; } i=0; while (argv[1][i] != '\0') { countmoji = argv[1][i]; count[countmoji]++; i++; } for(countmoji = 0x61; countmoji <= 0x7a;countmoji++) { if (count[countmoji] >= 1) { printf("%C :%4d \n", countmoji, count[countmoji]); } } return 0; } 上司からだされた練習用課題の一部です。 上記のソースで正確に動いてはいるんですが、上司から「間違ってはいないけど、中途半端なトコからメモリを使うな」とのことでして。 当方、組込み系の職場なので、メモリに関しては特にうるさいみたいです。 どう直したらよいのか困っております。 おそらく argv[0]→ox61 から argv[25]→0x7a のように頭から無駄なく使えと言っていることまではわかりました。 これをどう表現したらいいのかが。。。 Linux Fedora Core 6を使用しております。 お恥ずかしい質問ではございますが、よろしくお願いいたします。

  • fscanf

    fscanfを使って、ファイル(普通の英文が入っています)から一単語ずつ読み込んでいきたいと思っているのですが、どうすれば良いのかわかりません。 int main(int argc,char *argv[]){ FILE *fp; char *word; fp = fopen(argv[1], "r"); if(fp == NULL){ printf("error: not open file.\n"); return(0) ;} while( ){ fscanf(fp,"%[a-zA-Z]",word); printf("%s\n", word); fflush(stdout); } fclose(fp); return 0; } とりあえず上の様なプログラムで、一単語ずつ順番に単語を出力できるようにしたいと思っているのですが。 いろいろ変なところなど在ると思いますが、whileの条件など、どうすればよいか教えてください。

  • エラーが出ます

    12,51,13,123,133,551,… というコンマで区切られているファイルを読み込みたいです。数字は100文字です。どう書けば全部読み込めるでしょうか? よろしくお願いします。 int main(int argc,char *argv[ ]){ int line; int i; FILE *fp; fp = (argc > 1)? fopen(argv[1],"r"): stdin; if(fp==NULL){ perror("fopen"); exit(0); }   while(fscanf(fp,"%d",&line) != EOF){ printf("%d\n") } if(argc>1){ fclose(fp);   }

  • ファイル

    AからZまでの文字が何回出力されるか数えるプログラムなのですが、うまく出力されません。 どこを変えればよろしいでしょうか。 #include<stdio.h> #include<stdlib.h> #include<ctype.h> int count[26]; int main(void) { char str[100] = "xyzYZZ\n"; FILE *fp; char *p; int i; char ch; if((fp = fopen("myfile","w")) == NULL){ printf("ファイルを開くことが出来ません"); exit(1); } p = str; while(*p){ if(fputc (*p,fp) == EOF){ printf("ファイル書き込みエラー"); exit(1); } p++; } fclose(fp); if((fp = fopen ("myfile","r")) == NULL){ printf("ファイルを開くことが出来ません"); exit(1); } while((ch == fgetc(fp)) != EOF){ ch = toupper(ch); if( ch >= 'A' && ch <='Z' ) count[ch - 'A']++ ; } for( i=0 ; i<26 ; i++) printf("%c は %d 回出現\n",i + 'A', count[i]); fclose(fp); return 0; }

専門家に質問してみよう