単語の出現頻度を調べるプログラムの実行に問題がある

このQ&Aのポイント
  • ファイルからデータを読み込んで、単語の出現頻度を調べるプログラムを作成しました。
  • コンパイルは成功しましたが、実行しても画面に何も表示されません。
  • どこに問題があるか教えてください。
回答を見る
  • ベストアンサー

単語の出現頻度を調べるプログラム

 ファイルからデータを読み込んで、単語の出現頻度を調べるプログラムを作ろうと考えて、下記のようなプログラムを書いてみました。 #include <stdio.h> #include <string.h> main() { struct data {char word[128]; int freq;} word_data[128]; char words[128]; char term[128]; int i=0; int nw=0; int j; char buff[128]; FILE *fp_in=fopen("data.txt","r"); while(fgets(fp_in,128,buff)!=EOF){ char buff[128]; int k; for(k=0;k<=128;k++){ printf("%s",buff); if(('A'<=buff[k] && buff[k]<='Z')||('a'<=buff[k] && buff[k]<='z')) term[i++]=buff[k]; else if(i>0) term[i]='\0';} for(j=0;j<nw;j++){ if(strcmp(term,word_data[j].word)==0) break; if(j==nw) {strcpy(word_data[j].word,term); word_data[j].freq=1; nw++;} else if(j!=nw) {word_data[j].freq++; i=0;} }} for(j=0;j<nw;j++) printf("%s %d",word_data[j].word,word_date[j].freq); return 0;} コンパイルは通ったのですが、実行しても画面に何も表示されません。原因は何処にあるのでしょうか?分かる方がいましたら、ご回答宜しくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • wolv
  • ベストアンサー率37% (376/1001)
回答No.5

各行に複数単語がある場合にも対応してみました。 一部エラーチェックのコードも追加しました。 ------------------------------------------------- #include <stdio.h> #include <string.h> #define TRUE 1 #define FALSE 0 #define MAX_NWORDS 128 int isLetter(char c){   if( ('A'<=c && c<='Z') ||('a'<=c && c<='z') ) {     return TRUE;   }else{     return FALSE;   } } main() {   struct data {     char word[128];     int freq;   } word_data[MAX_NWORDS];   char term[128];   int nw=0;   int i,j,k;   char buff[128];   FILE *fp_in=fopen("data.txt","r");   while(fgets(buff,128,fp_in)!=NULL){     k=0;     while(buff[k]!='\n'){       while(! isLetter(buff[k]) && buff[k]!='\n') k++;       if(buff[k]=='\n')break;       i=0;       while(isLetter(buff[k])) term[i++]=buff[k++];       term[i]='\0';       for(j=0;j<nw;j++) if(strcmp(term,word_data[j].word)==0) break;       if(j==nw) {         strcpy(word_data[j].word,term);         word_data[j].freq=1;         nw++;         if(nw==MAX_NWORDS){           printf("more than %d words found.\n", MAX_NWORDS);           exit(1);         }       } else {         word_data[j].freq++;       }     }   }   for(j=0;j<nw;j++) printf("%s %d\n",word_data[j].word,word_data[j].freq);   return 0; }

linuxbeginner
質問者

補足

丁寧にありがとうございます。  もう1点質問させていただきたいのですが、最終結果を出力するときに辞書式順序(A,a,B,b,・・,Z,z)にソートする場合はどうすればいいのでしょうか?昨晩自力でやってみたのですが、どうもうまくいきません。アスキーコードの配列を用いる気がするのですが、アスキーコードですと、'A'~'Z'の後に、'a'~'z'が続きますよね。これをそのまま用いると、大文字が先にまとめて表示されてしまい、小文字が後にまとめて表示されてしまいますよね。 また、'A'='a'-32ですので、一旦、全ての小文字を大文字に変換して、大小比較をし、また元に戻すといった手段も考えてみたのですが、私にはソースコードが書けませんでした。  宜しければ、ご回答お願いできますでしょうか?  以下に私が書いてみたソースコードを挙げておきます。   #include <stdio.h> #include <string.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define MAX_NWORDS 128 int isLetter(char c){ if(('A'<=c && c<='Z')||('a'<=c && c<='z')){ return TRUE; }else{ return FALSE; } } main(){ struct data{ char word[128]; int freq; }; struct data word_data[MAX_NWORDS]; struct data word_data_cp[MAX_NWORDS]; char term[128]; int nw=0; int i,j,k,p,x; char m; char buff[128]; FILE *fp_in=fopen("data.txt","r"); while(fgets(buff,128,fp_in)!=NULL){ k=0; while(buff[k]!='\n'){ while(!isLetter(buff[k]) && buff[k]!='\n') k++; if(buff[k]=='\n')break; i=0; while(isLetter(buff[k])) term[i++]=buff[k++]; term[i]='\0'; for(j=0;j<nw;j++) if(strcmp(term,word_data[j].word)==0) break; if(j==nw){ strcpy(word_data[j].word,term); word_data[j].freq=1; nw++; if(nw==MAX_NWORDS){ printf(" more than %d words found.\n",MAX_NWORDS); exit(1); } }else{ word_data[j].freq++; }}} for(p=0;p<nw;p++){ for(j=0;j<nw-p-1;j++){ x=strcmp(word_data[j].word,word_data[j+1].word); if(x>0){ word_data_cp[j]=word_data[j]; word_data[j]=word_data[j+1]; word_data[j+1]=word_data_cp[j];} }} for(j=0;j<nw;j++) {printf("%s %d\n",word_data[j].word,word_data[j].freq);} printf("Total %d Words\n",nw); return 0; }

その他の回答 (6)

  • wolv
  • ベストアンサー率37% (376/1001)
回答No.7

修正版。動作確認ずみ。 strcmpを使っている部分は2箇所ありますが、 たぶん、2箇所めのstrcmpのみをこのstrcmp_dictorderに変更するのがよいと思います。 (大文字、小文字の違いによって意味が違う単語もありますので。) int strcmp_dictorder(char*a,char*b){ int i; char ca,cb; for(i=0;i<=strlen(a);i++){ ca=a[i];if(ca>='a')ca-=32 ; cb=b[i];if(cb>='a')cb-=32 ; if(ca!=cb) return ca-cb; } for(i=0;i<=strlen(a);i++){ if (a[i]!=b[i]) return a[i]-b[i]; } return 0; }

linuxbeginner
質問者

お礼

何度も丁寧にありがとうございます。 先ほど、実行してみましたところ、小文字の後に大文字が続く個所が数箇所あったのですが、 最初のforループに if(ca==cb-32) return 0; if(ca-32==cb) return 1; の2文を追加してみましたところ大文字→小文字の順番に上手く並びました。  文字列の比較では、strcmp関数を使うといったことしか 思い浮かばなかったので悩んでいたのですが、自分で関数を作ってしまえばいいのですね。また、教えて頂いた大文字と小文字を無視した大小関係の比較の書き方はなるほどと思いました。  お忙しいところ、丁寧に回答していただきまして本当にありがとうございました。これからも何か機会がありましたらよろしくお願いします。

  • wolv
  • ベストアンサー率37% (376/1001)
回答No.6

以下のような関数を定義して、strcmpの代わりにつかってみてください。返り値の符号は逆のほうがいいかもしれません。結果を見て適当に直してください。 動作確認はしていません。 下の関数のa[i]でエラーがでるようなら、 a[i]を*(a+i)に変えてみてください。 int strcmp_dictorder(char*a,char*b){ int i; char ca,cb; for(i=0;i<=strlen(a);;i++){ ca=a[i];if(ca>='a')ca-=32 cb=b[i];if(cb>='a')cb-=32 if(ca<cb)return -1; else if (ca>cb)return 1; else if (a[i]<b[i])return -1; else if (a[i]>b[i])return 1; else ;/*compare next letter*/ } return 0; }

  • wolv
  • ベストアンサー率37% (376/1001)
回答No.4

No3までを踏まえて動作するように書き換えてみました。制御構造も一部かえました。回答No2に示したようなdata.txtに対して動作確認ずみです。 ------------------------------------------------- #include <stdio.h> #include <string.h> main() {   struct data {     char word[128];     int freq;   } word_data[128];   char term[128];   int i;   int nw=0;   int j;   char buff[128];   FILE *fp_in=fopen("data.txt","r");     while(fgets(buff,128,fp_in)!=NULL){     int k;       i=0;     for(k=0;k<=128;k++){       if( ('A'<=buff[k] && buff[k]<='Z')||('a'<=buff[k] && buff[k]<='z') ) {         term[i++]=buff[k];       } else {         break;       }     }     if(i>0){       term[i]='\0';       for(j=0;j<nw;j++) if(strcmp(term,word_data[j].word)==0) break;       if(j==nw) {         strcpy(word_data[j].word,term);         word_data[j].freq=1;         nw++;       } else {         word_data[j].freq++;       }     }   }   for(j=0;j<nw;j++) printf("%s %d\n",word_data[j].word,word_data[j].freq);   return 0; } ------------------------------------------------- 注意:上記ソースコードは、行頭に全角スペースが入っているため、そのままコピーペーストしてもコンパイルできないことがあります。

  • wolv
  • ベストアンサー率37% (376/1001)
回答No.3

・char buffの宣言が2箇所にあります。そのためファイルから読み込んだ文字列は、while文の内部で使われていません。 ・fgetsの書式が違います。 fgets(buff,128,fp_in,128,buff)のはずです。 ・fgetsの返すファイル終端をあらわす値はEOFではなくNULLです。 ・結果表示部で、word_dat"e"[j]を表示しようとしています。 ・結果は、各単語の情報を表示するように改行も出力したほうがよさそうです。 ・char words[128]は使われていません。

  • wolv
  • ベストアンサー率37% (376/1001)
回答No.2

・各行のはじめの単語しかチェックしない仕様のようですが、それでいいのでしょか? ・行のはじめの1文字がA-Za-zのいずれかでない場合、term[0]の値が不定になります。この状態でstrcmpを実行すると問題がある気がします。 (上の2点は、各行が1単語からなり、その単語は行の1カラム目から始まる、という場合は問題ありませんが...) ・すでに登録した単語と同じ単語を見つけたばあい、iの値を0にリセットせずに次の行を読み込んでいます。次の行の単語は、term中の前回の単語の後ろに連結されます。 ( たとえば、データファイルが and and or だった場合、orを読み込んだ時点でのtermは、"andor"になります。(他の部分の動作に問題がなかったとしても) )

  • wolv
  • ベストアンサー率37% (376/1001)
回答No.1

 for(j=0;j<nw;j++){ のループの中に、  if(j==nw) という条件式があります。"thenの部分"は実行されません。

関連するQ&A

  • データの読み込みがうまくいかなくて、困っています

    プログラミング初心者です。 誤差逆伝播学習のプログラムを行っています。 C言語で、データの読み込み部分がうまくいかなくて、困っています。 borland , BCC Developerなどを用いてやっております。 やりたいことは、テキストファイルから数字を読み込み、それを行列に格納してデータとして送るということです。 その際に、テキストファイルで行と列で表示されたものを送ろうと考えています。30×30の、1と0で表示された絵と教師信号を読み取っています。 列だけの読み込みは正常に動いたのですが、行と列で表示されたものの読み込みができません。char型で変数を宣言しているので、数字として読み込めていないとか、そういったことがあるのでしょうか。o1[][],t[][]の部分に正しく値が送れるようにしたいです。 非常にわかりにくくて申し訳ないのですが、お分かりになる方がいたら、どこをどう変えれば良いか、教えて頂きたいです。 「間違っている列と行の読み込み」 //データをファイルから読み込む// void read_file(name) char *name; { int i,j,k; //ループカウンター// FILE *fp; //ファイルポインタ// char buff[MCHS]; //buffの最大文字数1024 //ファイルオープン// if((fp=fopen(name,"r"))==NULL){ fprintf(stderr,"%s:File open error !!\n",name); exit(-1); } //学習データを読み込む// fscanf(fp, "%d",&learning_pattern_no); //学習パターンの数読み込み fscanf(fp,"%d",&test_pattern_no); //テストパターンの数読み込み printf("学習パターンの数:%d\n",learning_pattern_no); //学習パターンの数表示 printf("テストパターンの数:%d\n",test_pattern_no); //テストパターンの数表示 i=0;j=0; while( fgets( buff, MCHS, fp ) != NULL ){ if(j<=learning_pattern_no+test_pattern_no-1){ for( k=0; k<MCHS; k++ ){ o1[j][i+k]=buff[k]; //o1[j][i+k]にbuff[k]を入れる printf("%c",buff[k]); //printfで確認 if( buff[k] =='\n'){ i=i+k; if (i==InputUnitNo){ i=0; j++; printf("%d",j); }//if(i==InputUnitNo)終了 break; }//if(buff[k])終了 }//for終了 }//if(j<=learn+test)終了 else{ //ここから教師信号の読み取り for( k=0; k<MCHS; k++ ){ t[i][k]=buff[k]; printf("%c",buff[k]); //教師信号の確認 if( buff[k] == '\n' ){ i++; break; }//if(buff[k])終了 }//for終了 }//else終了 }//while終了 } 「正常に動いた列だけの読み込み」 //データをファイルから読み込む// void read_file(name) char *name; { int i,j; //ループカウンター// FILE *fp; //ファイルポインタ// //ファイルオープン// if((fp=fopen(name,"r"))==NULL){ fprintf(stderr,"%s:File open error !!\n",name); exit(-1); } //学習データを読み込む// fscanf(fp, "%d",&learning_pattern_no); printf("学習データの数:%d\n",learning_pattern_no); for(i=0;i<learning_pattern_no; i++){ for(j=0;j<InputUnitNo; j++) fscanf(fp,"%lf",&o1[i][j]); for(j=0;j<OutputUnitNo; j++) fscanf(fp,"%lf",&t[i][j]); //教師信号 } //テストデータを読み込む// fscanf(fp,"%d",&test_pattern_no); printf("テストデータの数:%d\n",test_pattern_no); for(i=learning_pattern_no;i<learning_pattern_no+test_pattern_no;i++) for(j=0;j<InputUnitNo;j++) fscanf(fp,"%lf",&o1[i][j]); fclose(fp); }

  • 漢字を配列に入れたいのですが

    漢字を配列に入れたいのですが、うまくいきません。 3列、60行のcsvファイルを読み込んで配列に入れようをしているのですが、1列目、2列目、3列目にある漢字をそれぞれ配列に入れようとしているのですが、出力するとうまくいかないんです。誰か教えてください。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXBUFFSIZE 256 #define MAXWORDS 15 int split(char* words[], int length, char* split_ch,char* str){ int i,j; for(i=0;i<length;i++){ if((words[i] = strtok(str,split_ch))==NULL)break; str=NULL; } return(i); } int main(int argc, char* argv[]){ if(argc !=2){ printf("入力エラー"); return(0); } FILE *fp; char *ll, *words[MAXWORDS], ch, buff[MAXBUFFSIZE]; int i,j; unsigned int data1[60], data2[60], data3[60]; if((fp =fopen(argv[1],"r"))==NULL){ printf("ファイルが開けません。\n"); } j=0; ll= fgets(buff,MAXBUFFSIZE,fp); while((ll= fgets(buff,MAXBUFFSIZE,fp)) != NULL){ split(words, MAXWORDS, ",",ll); data1[j] = words[0]; data2[j] = words[1]; data3[j] = words[2]; j++; } printf("%s\n%s\n%s\n", data1,data2,data3); }

  • ネットで落ちていた「Excelで作ったデータ(CSVファイル)の読み込

    ネットで落ちていた「Excelで作ったデータ(CSVファイル)の読み込みプログラム」をそのままコンパイルして実行しようと思ったのですが、 sample.c: In function 'main': sample2.c:9: warning: return type of 'main' is not 'int' と、表示されてしまいます。 プログラミング初心者なので、どこが間違っているのかわかりません。 回答またはアドバイスの程、よろしくお願いいたします。 ネットで落ちていたプログラムを以下に記載します。 sample2.c #include <stdio.h> #define MAX_ITEM_SIZE 100 #define MAX_LINE_SIZE 1024 char *GetCSVItem(char *wp, char *buff, int size); void main(int argc, char *argv[]) { FILE *fp; char buff[MAX_LINE_SIZE], *wp, item[3][MAX_ITEM_SIZE]; int i1, len; if(argc != 2){ printf("コマンドの入力形式が間違っています.\n"); return; } fp = fopen(argv[1], "r"); if(fp == NULL){ printf("ファイルがオープンできません[%s].\n", argv[1]); return; } for(;;){ if(fgets(buff, MAX_LINE_SIZE, fp) == NULL) break; len = strlen(buff); if(len == 0 || buff[len-1] != '\n'){ if(feof(fp) == 0){ printf("データが不正です[%s].\n", buff); return; } } buff[len-1] = '\0'; wp = buff; if((wp = GetCSVItem(wp, item[0], MAX_ITEM_SIZE)) == NULL){ printf("エラー(1)\n"); break; } if((wp = GetCSVItem(wp, item[1], MAX_ITEM_SIZE)) == NULL){ printf("エラー(2)\n"); break; } if((wp = GetCSVItem(wp, item[2], MAX_ITEM_SIZE)) == NULL){ printf("エラー(3)\n"); break; } if(*wp != '\0'){ printf("エラー(4)\n"); break; } for(i1 = 0; i1 < 3; i1++){ printf("%d:%s\n", i1+1, item[i1]); } } fclose(fp); } char *GetCSVItem(char *wp, char *buff, int size) { int i1; buff[0] = '\0'; while(*wp == ' ' || *wp == '\t') wp++; if(*wp == '\0'){ return(NULL); } for(i1 = 0; i1 < MAX_ITEM_SIZE; i1++, wp++){ if(i1 >= size) return(NULL); buff[i1] = *wp; if(*wp == '\0'){ buff[i1] = '\0'; return(wp); } if(*wp == ','){ wp++; buff[i1] = '\0'; break; } } return(wp); }

  • プログラムが動きません。

    以前動いていたプログラムが動かなくなりました。 プログラムは3個のtxtファイル(2×2のデータ)で第1列の絶対値和、第2列の絶対値和を求め、1つのtxtファイルとして出力するものです。 #include <stdio.h> #define DATA_MAX 4 #define CH 2 static double data[CH][DATA_MAX]; int read_data(fp) FILE *fp;{ int i,j=0; while(1){ for(j=0;j<DATA_MAX;j++){ for(i=0;i<CH;i++){ fscanf(fp,"%lf",&data[i][j]); } if(feof(fp)!=0) break; } return j; } } void ecg_rr(fp,data_max) FILE *fp; { int i=0; char fname[64]; char fname1[64]; for(i=0;i<3;i++) { sprintf(fname1,"k%d.txt",i+1); fp = fopen(fname1,"r"); read_data(fp); fclose(fp); sprintf(fname,"sum.txt"); fp = fopen(fname,"a"); if(data[0][0]<0){data[0][0]=-data[0][0];} else{data[0][0]=data[0][0];} if(data[0][1]<0){data[0][1]=-data[0][1];} else{data[0][1]=data[0][1];} if(data[1][0]<0){data[1][0]=-data[1][0];} else{data[1][0]=data[1][0];} if(data[1][1]<0){data[1][1]=-data[1][1];} else{data[1][1]=data[1][1];} data[0][i]=data[0][0]+data[0][1]; data[1][i]=data[1][0]+data[1][1]; fprintf(fp,"%8.8f %8.8f\n",data[0][i],data[1][i]); fclose(fp); } } メイン関数には問題がないので省略しましたが、ここまでで問題というところはあるでしょうか?

  • cygwinを使ってcsvファイルを読み込み、出力させようとしています

    cygwinを使ってcsvファイルを読み込み、出力させようとしています。 とりあえず、読み込みのみのプログラムを作成し、 実行させてみたのですが(run ファイル名.csv と入力) 「Error: could not start C:\cygwin\home\ユーザー名ファイル名.csv」 と出力され、読み込みができず、困っています。 プログラム初心者です。 恐縮ですがご回答よろしくお願いします。 以下に、読み込みプログラムとcsvファイルを記載します。 (プログラムは拾い物です。) <プログラム> #include <stdio.h> #define MAX_ITEM_SIZE 100 #define MAX_LINE_SIZE 1024 char *GetCSVItem(char *wp, char *buff, int size); void main(int argc, char *argv[]) { FILE *fp; char buff[MAX_LINE_SIZE], *wp, item[3][MAX_ITEM_SIZE]; int i1, len; if(argc != 2){ printf("comand error nyuuryoku keishiki\n"); return; } fp = fopen(argv[1], "r"); if(fp == NULL){ printf("can not open file[%s].\n", argv[1]); return; } for(;;){ if(fgets(buff, MAX_LINE_SIZE, fp) == NULL) break; len = strlen(buff); if(len == 0 || buff[len-1] != '\n'){ if(feof(fp) == 0){ printf("data error[%s].\n", buff); return; } } buff[len-1] = '\0'; wp = buff; if((wp = GetCSVItem(wp, item[0], MAX_ITEM_SIZE)) == NULL){ printf("error(1)\n"); break; } if((wp = GetCSVItem(wp, item[1], MAX_ITEM_SIZE)) == NULL){ printf("error(2)\n"); break; } if((wp = GetCSVItem(wp, item[2], MAX_ITEM_SIZE)) == NULL){ printf("error(3)\n"); break; } if(*wp != '\0'){ printf("error(4)\n"); break; } for(i1 = 0; i1 < 3; i1++){ printf("%d:%s\n", i1+1, item[i1]); } } fclose(fp); } char *GetCSVItem(char *wp, char *buff, int size) { int i1; buff[0] = '\0'; while(*wp == ' ' || *wp == '\t') wp++; if(*wp == '\0'){ return(NULL); } for(i1 = 0; i1 < MAX_ITEM_SIZE; i1++, wp++){ if(i1 >= size) return(NULL); buff[i1] = *wp; if(*wp == '\0'){ buff[i1] = '\0'; return(wp); } if(*wp == ','){ wp++; buff[i1] = '\0'; break; } } return(wp); } <csvファイル> 1,2,3 11,12,13 21,22,23

  • cプログラミングについて

    以下はsample.txtというファイルを読み込み、辞書順に並べるプログラミングですが、どう正しく 直したらよいかわかりません。間違っている場所を指摘していただけたらと思います。 (間違えだらけで申し訳ありません) #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXLINE 500 void mysort(char *word[MAXLINE]) { int i,j; char *tmp; for(i=0;;i++){ for(j=i+1;; j++){ if(strcmp(word[j],word[i])==1){ tmp=word[i]; word[i]=word[j]; word[j]=tmp; } } } } int main(void) { int i; FILE *fp; char str[MAXLINE]; fp= fopen("sample.txt", "r"); if (fp == NULL) { printf("fopen error\n"); exit(1); } while(( fgets( str, MAXLINE, fp )) != NULL) mysort(str); for(i=0;; i++) printf("%s\n", str[i]); return 0; }

  • 出現文字の種類の数

    下記のプログラムのファイルから読み込んだ出現文字の種類の数を取得するにはどうすれば良いでしょうか? また、 ー アルファベットでは大文字を全て小文字に置換 ー スペース、タブ、改行記号はスペースに置換 ー 数字は全て0に置換 ー その他の記号はそのまま使う という条件になっています。 #include<stdio.h> #include<ctype.h> #include<math.h> int cnt[256]; char chs[256]; int n=256; int main(void) { int k; for(k=0;k<n;k++) cnt[k]=0; inputdata(); heapsort(1,n); printdata_reverse(); } void inputdata() { char c; char *fnam="English.txt"; FILE *fp; char bff[80]; char *p; int k; fp = fopen(fnam,"r"); while(fgets(bff,80,fp)!=NULL) { for(p=bff;*p;p++) { c = *p; if(isalpha(*p)) c=tolower(*p); if(isdigit(*p)) c = '0'; if(isspace(*p)) c = ' '; cnt[c]++; chs[c] = c; } } fclose(fp); } void heapsort(int s,int t) { int i; makeheap(s,t); for(i = t; i>= s+1; i--) { swap(s,i); heapify(s,i-1); } } void makeheap(int s,int t) { int i; for(i = t; i >= s; i--) heapify(i,t); } void heapify(int p,int q) { int r; r = 2*p; if(r <= q){ if(r < q && cnt[r] > cnt[r+1]) r = r+1; if(cnt[p] > cnt[r]){ swap(p,r); heapify(r,q); } } } void swap(int i, int j) { int temp1,temp2; temp1=cnt[i]; cnt[i]=cnt[j]; cnt[j]=temp1; temp2=chs[i]; chs[i]=chs[j]; chs[j]=temp2; } void printdata_reverse() { int k; int m=0; double pcnt[100]; for(k=0;k<n;k++) { if(cnt[k]>0) m += cnt[k]; } printf("Characters in UN Charter.\n"); printf(" # C occ. %%\n"); for(k=0;k<n;k++) { if(cnt[k]>0) { pcnt[k] = 1.0*cnt[k]/m; printf("%3d '%c' %5d %f\n", k,chs[k],cnt[k],pcnt[k]); } } } 実行結果 Characters in UN Charter. # C occ. % 1 ' ' 4576 0.190643 2 'e' 2804 0.116819 3 't' 1827 0.076115 4 's' 1464 0.060992 5 'o' 1339 0.055785 6 'a' 1315 0.054785 7 'n' 1313 0.054701 8 'r' 1257 0.052368 9 'i' 1103 0.045953 10 'h' 972 0.040495 11 'c' 755 0.031454 12 'l' 645 0.026872 13 'd' 639 0.026622 14 'u' 593 0.024705 15 'f' 492 0.020497 16 'p' 430 0.017914 17 'm' 400 0.016665 18 'g' 285 0.011874 19 '0' 278 0.011582 20 'b' 253 0.010540 21 '.' 238 0.009915 22 'v' 203 0.008457 23 'y' 199 0.008291 24 ',' 192 0.007999 25 'w' 167 0.006957 26 '-' 54 0.002250 27 'k' 38 0.001583 28 'x' 34 0.001416 29 ''' 30 0.001250 30 'j' 27 0.001125 31 '(' 20 0.000833 32 ')' 20 0.000833 33 'z' 17 0.000708 34 'q' 13 0.000542 35 ':' 11 0.000458

  • 出現文字の種類の数

    下記のプログラムのファイルから読み込んだ出現文字の種類の数を取得するにはどうすれば良いでしょうか? また、 ー アルファベットでは大文字を全て小文字に置換 ー スペース、タブ、改行記号はスペースに置換 ー 数字は全て0に置換 ー その他の記号はそのまま使う という条件になっています。 #include<stdio.h> #include<ctype.h> #include<math.h> int cnt[256]; char chs[256]; int n=256; int main(void) { int k; for(k=0;k<n;k++) cnt[k]=0; inputdata(); heapsort(1,n); printdata_reverse(); } void inputdata() { char c; char *fnam="English.txt"; FILE *fp; char bff[80]; char *p; int k; fp = fopen(fnam,"r"); while(fgets(bff,80,fp)!=NULL) { for(p=bff;*p;p++) { c = *p; if(isalpha(*p)) c=tolower(*p); if(isdigit(*p)) c = '0'; if(isspace(*p)) c = ' '; cnt[c]++; chs[c] = c; } } fclose(fp); } void heapsort(int s,int t) { int i; makeheap(s,t); for(i = t; i>= s+1; i--) { swap(s,i); heapify(s,i-1); } } void makeheap(int s,int t) { int i; for(i = t; i >= s; i--) heapify(i,t); } void heapify(int p,int q) { int r; r = 2*p; if(r <= q){ if(r < q && cnt[r] > cnt[r+1]) r = r+1; if(cnt[p] > cnt[r]){ swap(p,r); heapify(r,q); } } } void swap(int i, int j) { int temp1,temp2; temp1=cnt[i]; cnt[i]=cnt[j]; cnt[j]=temp1; temp2=chs[i]; chs[i]=chs[j]; chs[j]=temp2; } void printdata_reverse() { int k; int m=0; double pcnt[100]; for(k=0;k<n;k++) { if(cnt[k]>0) m += cnt[k]; } printf("Characters in UN Charter.\n"); printf(" # C occ. %%\n"); for(k=0;k<n;k++) { if(cnt[k]>0) { pcnt[k] = 1.0*cnt[k]/m; printf("%3d '%c' %5d %f\n", k,chs[k],cnt[k],pcnt[k]); } } } 実行結果 Characters in UN Charter. # C occ. % 1 ' ' 4576 0.190643 2 'e' 2804 0.116819 3 't' 1827 0.076115 4 's' 1464 0.060992 5 'o' 1339 0.055785 6 'a' 1315 0.054785 7 'n' 1313 0.054701 8 'r' 1257 0.052368 9 'i' 1103 0.045953 10 'h' 972 0.040495 11 'c' 755 0.031454 12 'l' 645 0.026872 13 'd' 639 0.026622 14 'u' 593 0.024705 15 'f' 492 0.020497 16 'p' 430 0.017914 17 'm' 400 0.016665 18 'g' 285 0.011874 19 '0' 278 0.011582 20 'b' 253 0.010540 21 '.' 238 0.009915 22 'v' 203 0.008457 23 'y' 199 0.008291 24 ',' 192 0.007999 25 'w' 167 0.006957 26 '-' 54 0.002250 27 'k' 38 0.001583 28 'x' 34 0.001416 29 ''' 30 0.001250 30 'j' 27 0.001125 31 '(' 20 0.000833 32 ')' 20 0.000833 33 'z' 17 0.000708 34 'q' 13 0.000542 35 ':' 11 0.000458

  • C言語のプログラムをエクセルに書き込む方法

    C言語のプログラムをエクセルに書き込みたいのですが、自分が理解していないのか、上手にできません。 前、質問(No.421727)して、教えてもらったのですがソートプログラムの実行結果もおかしい感じです。 #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 1000 void filewrite(int j,int i,int a[]); void main(void){ int min,s,t,i,j,k,a[N]; srand((unsigned int)time(NULL)); for(i=0;i<N;i++) a[i]=rand()%1000+1; for(j=0;j<i-1;j++){ min=a[j]; s=j; for(k=j+1;k<i;k++){ if(a[k]<min){ min=a[k]; s=k; } } t=a[j];a[j]=a[s];a[s]=t; if(j%100 == 99){ for(s=0;s<i;s++) printf("%d\t",a[s]); } filewrite(j,i,a); } } void filewrite(int j,int i,int a[]) { int s; FILE *fp; char name[15]; printf("\nfilename="); scanf("%s",name); if((fp=fopen(name,"w"))==NULL){ printf("\nCan't open the sourse file\n"); exit(1); } if(j%100 == 99){ for(s=0;s<i;s++) fprintf(fp,"%d\n",a[s]); fclose(fp); } } よろしくお願いします。

  • 助けてください! c言語のプログラムです。

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define KAMOKU_SUU 5 #define AVE_INDEX KAMOKU_SUU typedef struct { char name[32]; int scor[KAMOKU_SUU]; int mean; } STUDENT; int round(double d) { if (d < 0) return (int)(d-0.5); else return (int)(d+0.5); } #define ARRAY_OF(a) (sizeof (a) / sizeof (a[0])) int main(int argc,char* argv[]) { int i, j,k, n; int nStudets; double avrg[KAMOKU_SUU + 1]; double stdv[KAMOKU_SUU + 1]; STUDENT *mem; char buff[80]; if (argc < 2) { printf("!パラメータ不足\n"); return 1; } nStudets = atoi(argv[1]); mem = (STUDENT*)malloc(sizeof (STUDENT) * nStudets); if (mem == NULL) { printf("!アロケーション\n"); return 2; } memset(avrg, 0, sizeof (avrg)); memset(stdv, 0, sizeof (stdv)); printf("生徒 %d 名分の成績を入力してください:\n", nStudets); for (k = 0; k < nStudets; k++) { printf("%d 人目の点数と名前 > ", k + 1); gets(buff); strcpy(mem[k].name, strtok(buff," ")); mem[k].mean = 0; for (j = 0; j < KAMOKU_SUU; j++) { int i = mem[k].scor[j] = atoi(strtok(NULL," \n")); mem[k].mean += i; avrg[j] += i; stdv[j] += i * i; } mem[k].mean = round(mem[k].mean * 1.0 / KAMOKU_SUU); } for(j = 0; j < KAMOKU_SUU; j++) { avrg[AVE_INDEX] += avrg[j]; stdv[AVE_INDEX] += stdv[j]; avrg[j] = avrg[j] / nStudets; stdv[j] = sqrt(stdv[j] / nStudets - avrg[j] * avrg[j]); } n = nStudets * KAMOKU_SUU; avrg[AVE_INDEX] = avrg[AVE_INDEX]/ n; stdv[AVE_INDEX] = sqrt(stdv[AVE_INDEX] / n) - (avrg[AVE_INDEX] * avrg[AVE_INDEX]); printf("\n成績表\n"); printf("# NAME"); for (i = 1; i <= KAMOKU_SUU; ++i) printf(" #%d ", i); printf("MEAN\n"); for (k = 0; k< nStudets; k++) { printf("%d %10s",k+1,mem[k].name); for (j = 0; j < KAMOKU_SUU; j++) { printf(" %3d",mem[k].scor[j]); } printf(" %3d\n",mem[AVE_INDEX].mean); } printf("------------------------------------\n"); printf(" %10s","average"); for(j = 0; j < ARRAY_OF (avrg);j++) { printf(" %3.0f",avrg[j]); } printf("\n"); printf(" %10s","st.dev."); for ( j = 0; j < ARRAY_OF (stdv); j++) { printf(" %3.0f",stdv[j]); } printf("\n"); printf("正常終了\n"); return 0; }  実行してもできません。原因が全く分かりません。 お願いします。 修正してくださるとありがたいです。

専門家に質問してみよう