2

テキストファイルの単語数をカウントする関数を実装しようとしています。

これが私のこれまでの試みです。

#include <stdio.h>
#include <string.h>

int main()
{
  FILE *fp;
  char word[1000];
  int count = 0, i;
  int *ptr = NULL;

  printf("Enter filename: ");
  scanf("%s", word);
  fp = fopen(word, "r");

  while(fscanf(fp, "%s", word) != EOF) //dynamically allocate contents of the file into word
    ptr = (int *)malloc(sizeof(int));
  for(i = 0; i < 4000; i++)
  {
    if(word[i] == ' ')
      count++;
  }
  printf("Total: %d", count);
  return 0;
}//main

gcc-を使用してコンパイルすると、「変数' ptr'が設定されているが使用されていない」などのエラーが発生しますが、ファイルの内容をに動的に割り当てたときに使用したと思いましたword[80]

私の単語カウンターに重大な問題があると思います...明らかに200以上の単語がある場合も0を返します。誰かが私を教えてくれませんか?

4

7 に答える 7

1

うーん、でもファイルの内容をword [80]に動的に割り当てたときに使ったと思いましたか?

いいえ、何度も何度も設定します。

int *ptr = NULL;   // <-- pointer is set to null

while(fscanf(fp, "%s", word) != EOF) 
  ptr = (int *)malloc(sizeof(int)); // ptr is being set to some memory, again and again
                                    // also this could be a nice memory leak

そのため、gccは「変数'ptr'は設定されていますが、使用されていません」と言っています。これは使用しないためです。

だから問題:

  1. ptrは設定されていますが、使用されていません
  2. (sizeof int)バイトを(int *)に割り当てる
  3. メモリリーク、常に上書きptr
  4. fscanf()成功した割り当ての数を返します。EOFの代わりにそれを使用する必要があります
  5. word[]長さは1000ですが、ループしています4000
  6. fscanf()結果を「単語」に入れることで、そこにあるものを常に上書きしている
  7. あなたはのリターンをキャストするべきではありませんmalloc()
  8. "%s"実際に"%999s"は入力の長さを制限する必要がありますが、1000を使用すると、とにかく安全だと思います。

頭のてっぺんから見えるのはそれだけです。それらを修正して、どこに到達するかを確認してください。

于 2013-02-20T19:42:27.537 に答える
0

何を取り出すべきかを示すために、あなたのものを変更しました。ファイルに対して「wc」を実行し、ファイルから単語数を取得することで、Linux で動作することを確認できます。

于 2013-02-20T19:59:07.677 に答える
0

「ファイルの内容を単語に動的に割り当てる」というコメントから判断すると、コードが実際に何をしているのかについて少し混乱しているようです。

while(fscanf(fp, "%s", word) != EOF)
    ptr = (int *)malloc(sizeof(int));

fscanfが返されるまで、実際に繰り返し呼び出しますEOF。また、呼び出しごとfscanfにファイルから単語を読み取り、一時バッファーに格納しますが ( word)、このループの本体は意味をなしません。1 つの整数を保持するのに十分な大きさのメモリを動的に割り当て、ptrこのメモリ (割り当てられたが割り当て解除されていないメモリ。これもメモリ リークを引き起こします) を指すようにします。

この関数は「正常に一致して割り当てられた入力項目の数を返す」ため、代わりにの戻り値fscanfが等しいかどうかを確認できます。ループは実際には次のようになります。1while

while(fscanf(fp, "%s", word) == 1)
    count++;

char word[1000];また、長さの配列を定義して1000いますが、forループには 4000 回の繰り返しがあり、配列の境界外の要素にアクセスしようとしているため、未定義の動作が発生することに注意してください。また、ループのロジックは、に格納されforているスペース () をむしろカウントしているようです。このループはあなたにとってまったく役に立ちません。ただ取り除いてください。' 'word

お役に立てれば :)

于 2013-02-20T19:45:07.367 に答える
0

ここで多くのことが間違っています。fscanf(fp, "%s", word)ファイルから新しい単語を取得し、呼び出すたびに単語バッファーに保存します。while ループには開き/閉じ中かっこがないため、ファイルから読み取るすべての単語に対して、新しい int* を割り当てます。ファイルからすべてを読み取った後、ファイル内の最後の単語の単語バッファーを調べてスペースを数えますが、1000 ではなく 4000 を反復しています。「C++ 単語数」を検索してみてください。この回答を入力するのにかかった時間よりも短い時間で、有効な解決策を見つけることができると確信しています。

于 2013-02-20T19:34:50.233 に答える
0

残念ながら、あなたのプログラムには多くの問題があります。手始めに、「単語」でインデックスのオーバーランがあります (1000 バイトが割り当てられていますが、インデックスは 4000 まで実行されます)。

while ループで文字列を読み取るたびに整数を割り当てるのはなぜですか?

プログラムは次のようになります。

char buffer[1000];
int count = 0;
while(fscanf(fp, "%s", buffer) != EOF) count++;

編集: 申し訳ありませんが、文字を読んでいると思っていましたが、上記は変更を反映しているはずです。

于 2013-02-20T19:36:20.783 に答える
0
#include <stdio.h>

int main()
{
  FILE *fp;
  int count = 0;
  char word[15], c;

  printf("Enter filename: ");
  scanf("%s", word);
  fp = fopen(word, "r");
  if(fp == NULL)
    return -1;

  while((c = fgetc(fp)) != EOF) {
    if(c == ' ')
      count++;
  }

  fclose(fp);
  printf("Total: %d", count+1);

  return 0;
}

これは本当に簡単です。

于 2013-02-20T19:46:55.380 に答える