• ベストアンサー

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

実は作成してみたいプログラムがあります。 それは単語カウントプログラムです。 入力するテキストのファイル中の単語(大文字小文字区別なし)を数えて、そして全体の単語数&それぞれの単語ごとの数を表示させるプログラムを作成してみたいです。分かりやすく言いますと以下の通りです。 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% (2127/6290)
回答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