• ベストアンサー

作成したいプルグラムがあります。

実は作成してみたいプログラムがあります。 それは単語カウントプログラムです。 入力するテキストのファイル中の単語(大文字小文字区別なし)を数えて、そして全体の単語数&それぞれの単語ごとの数を表示させるプログラムを作成してみたいです。分かりやすく言いますと以下の通りです。 This is a pen. This is a book. を入力すると、 total:8 This :2 is:2 a:2 pen:1 book:1 と出力されるプログラムです。 今までやってみてできた段階は #include <stdio.h> int main(void) { char s[256]; char t[256]; int i, n[3] = {0, 1, 0}; int j, o[3] = {0, 1, 0}; /* 標準入力より文字列を取得 */ printf(""); printf(""); fgets(s, sizeof s, stdin); fgets(t, sizeof t, stdin);      /* 文字列内の単語数を取得*/ for (i = 0; s[i]; i++) if (s[i] == ' ') /* 単語の区切りは空白文字*/   n[1]++; for (j = 0; t[j]; j++) if (t[j] == ' ') /* 単語の区切りは空白文字*/   o[1]++;      printf("total:%d\n\n", n[1]+o[1]);      return(0); } です。これ以降は分からなくて、参考になれるご指導をお願いいたします。

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

  • ベストアンサー
  • yama5140
  • ベストアンサー率54% (136/250)
回答No.4

>これ以降は分からなくて、参考になれるご指導をお願いいたします。 ★この質問を見た(読んだ)人は、「これ」が判らないと思います。  ・どうして n[1]++; なのか。n[0], n[2] は何に使うのか。  ・なぜ空白をカウント・出力するのか。 ★「参考になれる」かどうかは、質問者様だけが判断できること。  ↑「回答者」にしてみれば、高いハードルだなぁ。 ----- 高いハードルは、くぐってと年寄りが・・--------- ★手作業だったら、どうするか。  ・まず、最初の単語をメモし、「正」の字の横一(◆)。  ・次の単語が、前の単語と同じ(既出)なら、「正」の字の縦(順次)。  ・違えば、新たにメモ・・この繰り返しだよね。  これをプログラムする(↓1つの方法、他の方法もいっぱいあるはず)。  ・メモ用紙の代わりに、構造体を定義。   typedef struct{    int iCount;    // カウンタ    char cTango[32]; // 単語   }TANGO;   TANGO sWork[1000]; // [1000] は適宜調整(>テキスト内ユニーク単語数)   int igAllCount = 0;  ・1行読み込み、「単語」切り出し、既出判定。   ▽初物だったら構造体に格納、カウンタを1に初期化(◆)。     格 納: strcpy( sWork[igAllCount].cTango, cStr );     初期化: sWork[igAllCount++].iCount = 1; // igAllCount++ はここだけ     既 出: sWork[ x ].iCount++; // x 番目に格納したものと一致   ▽難物は、「『単語』切り出し」。    ・大小 52 文字以外をデリミタとするか、it's の ' はどうするか。       (あらかじめ定めておく)    ・デリミタを全て NULL にしておくのも1つの方法。そして、     strcpy( cStr, &cBuf[k] );     for( i = 0; i < igAllCount; i++ ){ // 判定       if( 0 == strcmp( sWork[i].cTango, cStr ) ){ // 既出 ★て書いてきたけど、やっぱハードルは越えなくちゃダメかな。

C_beginner
質問者

お礼

いろいろのご指導有難うございます。 やはりいきなり単語カウントプログラムを作りたくても基本をしっかり覚えていないわけですから組むのに無理が出てます。基本を踏まえてから少しずつ作り上げたいと思いました。 皆さんのご指導有難うございました。

その他の回答 (3)

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.3

> This :2 > is:2 > a:2 > pen:1 > book:1 出力順に、何らかの決め事はありますか? 上記の例を見る限りにおいては 単語の登場順のように見えますが、そういう仕様ですか?

C_beginner
質問者

お礼

はい、単語の登録順に出力したいと思っておりますが。

  • buriburi3
  • ベストアンサー率44% (353/792)
回答No.2

stdinを使っているのでfopenする必要はありません。 現状のプログラムのままでファイルから入力したい場合には実行時に入力ファイルをリダイレクトすれば良いです。 ※ プログラムがTEST.EXE 入力ファイルがDATA.TXT であれば。 ※ TEST < DATA.TXT キーボードから入力する場合には[cntl]+[D]でEOFを入力できます。 後は…先は長いですから頑張って… (^^;)

C_beginner
質問者

お礼

ご指導有難うございます。使ってみます。

  • Tasuke22
  • ベストアンサー率33% (1799/5383)
回答No.1

これは先が長いかもしれませんね。 3点書きます。 まず、fgetsの前にfopenが必要で、fgetsが終わると fcloseが必要です。 fgetsは前もって終わらせるのではなくて、eofにな るまで繰り返してfgetsするものです。 単語の区切りは(これをデリミタという)空白とし ていますが、空白以外にもデリミタはあるでしょう。 例えば「,」「.」改行、eof等、「:」や「;」も 入れるべきかもしれません。 ついでにスペースが続いた場合のことを考慮しま しょう。なおスペースは''ではありません。 ' 'です。 最初のprintf 2行が意味不明。改行とかしたいの ならtotalを印刷する時に、同時に行うべき。 forの後ろにifを使っているので括弧でくくった方 がforがどこまで有効かはっきりする。 括弧と段落は合わせるべきでしょう。 3つと言いながら沢山書いてしまいました。

C_beginner
質問者

お礼

沢山のご指導有難うございます。やはりまだまだ先が長いですね。 >最初のprintf 2行が意味不明。改行とかしたいの  ならtotalを印刷する時に、同時に行うべき。 #そうですね。二行に改行したくprintfを二回入れてしまいました。 #そして括弧と段落は合わせるの方が分かりやすいですもんね。

関連するQ&A

  • 解説求む

    #include <stdio.h> int main(void) { char s[256]; int i, n[3] = {0, 1, 0};   printf("英文を入力して下さい:"); fgets(s, sizeof s, stdin); for (i = 0; s[i]; i++) if (s[i] == '\n') break; s[i] = '\0'; for (i = 0; s[i]; i++) n[0]++; for (i = 0; s[i]; i++) if (s[i] == ' ') n[1]++; for (i = 0; s[i]; i++) if (s[i] == '.' || s[i] == '?' || s[i] == '!' || s[i] == ',' || s[i] == '/') n[2]++; printf("文字数は%dです。\n", n[0]); printf("単語数は%dです。\n", n[1]);   printf("文の数は%dです。\n", n[2]); return 0; } このプログラムゎ英文の文字数と単語数と文数を数えて表示させるものなんですが、これのフローチャート的なものを詳しく教えていただけるとありがたいです。全体的にあんまり理解できなくて…

  • 英単語(英文字で最大15文字)を*があわられるまで1つずつ読み込み、読

    英単語(英文字で最大15文字)を*があわられるまで1つずつ読み込み、読み込んだ英単語の文字数を計算して同一文字数の単語の出現回数を表示するプログラムです。 以下のプログラムを関数の引数及びその中実行文中でポインタ変数を使用するものを作りたいのですが、以下のプログラムは正常に動いているのですが、関数が使われていません。どう分けていいか分からないので教えてくださると助かります。 #include<stdio.h> int main(void) { char mojiretu[15],*pmoji int con[15]={0},i,j; pmoji=&mojiretu[0]; printf("課題データ\n"); scanf("%s",mojiretu); while(*pmoji!='*') { for(j=0;*(pmoji+j)!='\0'j++) {} con[j-1]++; scanf("%s",mojiretu); } printf("文字数\t出現回数\n") for(i=0;i<=14;i++) printf("%d\t%d\n",i+1,con[i]); }

  • C言語:単語カウント

    英文中に現れる異なる単語の数を表示するプログラムがわかりません。 例えば 「the a the」と入力されたら the=2 a=1 と表示されるプログラムです。 なんとかカウントはされるのですが出力がうまくいきません。同じ単語も表示されてしまいます。 どなたかご教授お願いします。 WindowsXP、コンパイラはBCCを使っています。 #include <stdio.h> #include <string.h> #define MAX 256 int main() { struct { char word[MAX]; int counter; }list[50]; int i,j,total=0; i=0; while(scanf("%s",list[i].word)!=EOF){ /*キーボードから文字列をすべて読み込む*/ total++; i++; } list[0].counter=1; for(i=0;i<=total;i++,list[i].counter=0){ /*比較*/ for(j=1;j<=total;j++){ if(strcmp(list[i].word,list[j].word)==0){ list[i].counter++; } } } for(i=0;i<=total;i++){ printf("%s %d\n",list[i].word,list[i].counter); /*出力 the=2 a=1 the=1となってしまう*/ } return(0); }

  • プログラミング(ポインタ/文字列処理)を教えて下さい

    プログラミング(ポインタ/文字列処理)を教えて下さい 英単語(最大で15文字まで)を*が現れるまで1つずつ読み込み、読みこんだ英単語の文字数を計算して表示するプログラムです。英単語は文字型配列を使用します。 1、関数の引数及びその中の実行文中で配列を使用 2、関数と引数及びその中の実行文中でポインタ変数を使用する この2つのプログラムを別々に作らなければならないのですが、当方関数をの使い方が今一分らないので以下のプログラムを関数での作成方法を教えて下さい。 これが関数で作らなければいけないプログラムです #include<stdio.h> int main(void) { char mojiretu[15]; int con[15]={0},i,j; printf("課題データ\n"); scanf("%s",mojiretu); while(mojiretu[0]!='*') { for(j=0;mojiretu[j]!='\0'j++) {} con[j-1]++; scanf("%s",mojiretu); } printf("文字数\t出現回数\n") for(i=0;i<=14;i++) printf("%d\t%d\n",i+1,con[i]); } こちらはポインタ変数を用いていますが関数になっていません。 #include<stdio.h> int main(void) { char mojiretu[15],*pmoji int con[15]={0},i,j; pmoji=&mojiretu[0]; printf("課題データ\n"); scanf("%s",mojiretu); while(*pmoji!='*') { for(j=0;*(pmoji+j)!='\0'j++) {} con[j-1]++; scanf("%s",mojiretu); } printf("文字数\t出現回数\n") for(i=0;i<=14;i++) printf("%d\t%d\n",i+1,con[i]); } 2つとも正常に動いてます。どちらか一つでもいいので関数での書き方を詳しくおねがいします。

  • 名簿作成 表示について

    名簿作成のプログラム、コンパイルしたときに 自分で入れた名簿を全て表示させたいのですが main関数をどう変えれば出来るでしょうか? このままだと、1人分しか表示されません。 初心者なので丁寧に教えてくださればと思います。 #include<stdio.h> #define NAMELEN 30 #define NOLEN 10 char s; struct gakuseki{ char no[NOLEN]; char name[NAMELEN]; int age; }; struct gakuseki input_data(void){ struct gakuseki st; printf("input student number>"); scanf("%s",&st.no); /*getchar(); fgets(st.no,NOLEN,stdin);*/ printf("input name>"); getchar(); fgets(st.name,NAMELEN,stdin); printf("input age>"); scanf("%d",&st.age); printf("continue?(y/n)"); scanf("%s",&s); return st; }; void output_data(struct gakuseki g){ printf("----------------------------------\n"); printf("student number : %s\n",g.no); printf("name : %s\n",g.name); printf("age : %d\n",g.age); }; int main(){ int i,j; struct gakuseki stud; for(i=0;i<3;i++){ /* struct gakuseki stud;*/ stud=input_data(); if(s=='n') { break; }; }; output_data(stud); };

  • strstrを利用しない文字列検索について

    キーボードから入力した文字列 str に対し, This is~の文字列中に str が出現するかどうかを判定して表示するプログラムを作成したいのですが、うまくコンパイルができません。 条件ですが、、、 ・forループを利用し、0文字目、1文字目と順に検索していく ・strstr関数およびstring.hを利用しない です。このプログラムをいじって教えてほしいです。 ややこしくて答えづらい質問かと思いますが、有識者の知恵を拝借したいです。よろしくお願いします。 #include <stdio.h> int main(void) { char str[256]; char s[] = "This is a pen. That is an apple."; int i,j,k,checker; printf("This is a pen. That is an apple.\n\n"); gets(str); for(j=0;j<256;j++) { for(i=j,k=0;str[k]!='\0';k++,i++) { if(str[k]==s[i]) { checker=1; } else { checker=0; } } } if(checker==0) { printf("NG!その文字列は含まれていません。\n"); } else { printf("OK!その文字列は含まれています。\n"); } }

  • c言語のscanfとfgetsについて

    2つの単語A, Bを入力して、AがBに含まれるか否かというプログラムで 以下のようなものを作成しました。 そこで質問なのですがscanf()をfgets()に変えるとうまく動作しません どこが間違ってますか? 変更したいfgets fgets(key, sizeof(key), stdin); fgets(word, sizeof(word), stdin); ------------------------------------------------- int main(void) { char key[101], word[101]; scanf("%s", key); scanf("%*c%s", word); if (strstr(word, key) != NULL) { printf("Find %s In %s\n", key, word); } else { printf("Not Find\n"); } return 0; }

  • あと少しなんですが・・・

    入力: This is a pen. 入力文字列:[ This is a pen. ] 出力文字列;[ pen. a is This ] ――――――――――――――――――― 上に示したように単語の順番をさかさまにして表示するプログラムを作りました。しかし、今のプログラムでは、最初に空白が来たり、空白が連続すると正しく表示できません。どこを修正すればいいのか教えてください。 -------------------------- #include <stdio.h> #define BUF 1024 void out(int,char); int main(void){ char in[BUF]; /* 入力された文字列を保存する */ char out[BUF]; /* inoput の内容を単語逆順にして保存する*/ int wordcount; /* 文字カウント */ char *in_ptr,*out_ptr; /* それぞれの文字列の文字をさすポインタ */ int i,j,a,b; /* 繰り返し用カウンタ */ /* メッセージの表示+文字列の入力 */ printf("入力: "); fgets(in, sizeof(in), stdin); /* ポインタの初期化 */ in_ptr = in; out_ptr = out; /* 単語数の初期化 */ wordcount = 0; /* 単語数を数える作業 */ while(*in_ptr != '\n'){ if(*in_ptr!=' '&&(*(in_ptr+1)==' '||*(in_ptr+1)=='\n')){ wordcount++; } in_ptr++; } /* メッセージの表示+単語数の表示 */ printf("\n文字数のカウント開始\n"); printf("文字数のカウント終了: %d単語\n",wordcount); printf("\n入力文字列:[ %s ]\n", in); printf("出力文字列;[ "); /* 単語逆順処理作業 */ b=0; for(a=0;a<wordcount;a++){ j=0; b++; in_ptr = in; for(i=0;i<(wordcount-b);i++){ while(*in_ptr!=' '){ j++; in_ptr++; } in_ptr++; } /* ポインタを単語の頭に持っていく */ in_ptr= in + (j+(wordcount-b)); /* inをoutにコピー */ while(*in_ptr!='\0' && *in_ptr!=' ' && *in_ptr!='\n'){ *out_ptr = *in_ptr; in_ptr++; out_ptr++; } if(*in_ptr==' '||*in_ptr=='\n'||*in_ptr=='\0'){ *out_ptr = ' '; out_ptr++; } } printf("%s]\n",out); return 0; }

  • このプログラムを解読してください。

    これは、楕円の内部と外部に色を塗るプログラムです。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define MS 200 main() { char fi[50]; int i,j; double x0,y0,a,b; FILE *fp; unsigned short header[13]={0x4d42,54490,1,0,0,26,0,12,0,MS,MS,1,24}; unsigned char bmp[MS][MS][3]; for(i=0;i<=MS-1;i++) { for(j=0;j<=MS-1;j++) { bmp[i][j][0]=0; bmp[i][j][1]=255; bmp[i][j][2]=0; } } printf("中心のx座標:"); fgets(fi,50,stdin); x0=atof(fi); printf("中心のy座標:"); fgets(fi,50,stdin); y0=atof(fi); printf("短径:"); fgets(fi,50,stdin); a=atof(fi); printf("長径:"); fgets(fi,50,stdin); b=atof(fi); for(i=0;i<=MS-1;i++) { for(j=0;j<=MS-1;j++) { if((pow(j-x0,2.0)/pow(a,2.0))+(pow(i-y0,2.0)/pow(b,2.0))<=1) { bmp[i][j][0]=0; bmp[i][j][1]=0; bmp[i][j][2]=255; } } } printf("Input file name:"); fgets(fi,50,stdin); fi[strlen(fi)-1]='\0'; if((fp=fopen(fi,"wb"))==NULL) { fprintf(stderr,"Error: file open [%s].\n",fi); exit(1); } fwrite(header,2,13,fp); fwrite(bmp,1,MS*MS*3,fp); fclose(fp); }

  • c言語 文字列と配列

    #include<stdio.h> int charlen(int n); void cap2sml(int b); int main() { char a[100],b[100]; int n,i; /*Input CARACTERS*/ printf("CAPITAL?\n"); fgets(a,100,stdin); charlen(n); printf("total cahrs=%d\n",n); //printf in main cap2sml(i); printf("small=%s\n",b); return(0); int charlen(int n) n=0; while(1){ if(a[n]=='\0') break; n++; } void cap2sml(int b) int i; for(i=0;a[i]!='\0';i++){ b[i]=a[i]+0x20; } b[i]='\0' } のプログラムでエラーがでるのですが、どこを直せばよいでしょうか? ユーザー関数を使い文字列(大文字)を入力したときの文字列の長さと大文字を小文字に変化するプログラムです

専門家に質問してみよう