1

以下のコードに示すように、fscanfを使用してファイルからデータを取得するときに、「!feof(fin)」の前とそれ以降の2回使用されるのはなぜですか。

fscanf(fin, "%s", letta);
while(!feof(fin)){

    fscanf(fin, "%s", letta);
}

読んだ言葉は同じではありませんか?

4

4 に答える 4

1

ファイルから2回読み取るため、読み取られる単語は同じではありません。毎回異なるデータを取得します。

ファイルの終わりにいるかどうかを確認するためのテストの条件。これwhileを行うには、読み取りが試行されている必要があります。これには、ループのfscanf() 前が必要です。

ループに入ったら、ファイルからの読み取りを続行します。おそらく、読み取っているデータを処理するためのコードがループ内にさらに存在するでしょう。

投稿したコードで、最初の読み取り試行でファイルの終わりに遭遇した場合、(while)ループには入りません。

これをdo-while、テストがループの最下部にある構成と比較してください(つまり、読み取りはループの「最下部」で1回だけ発生します)。そこでは、常に少なくとも1回はループに入ります。

于 2012-06-20T12:51:02.830 に答える
1

ここでこのように使用しても意味がないかもしれませんfeof()が、Cを学習している多くの人(私が間違っているとお詫びします)は「したい」ようです。

実際には、fscanf()それ自体に戻り値があります。ファイルが終了すると、要求されたスキャンを実行できなくなり、そのように通知されます。EOFファイルが終了すると、特別な定数も返されます。したがって、 fscanf():の戻り値をループするだけです。

while( fscanf(fin, "%s", letta) == 1 )
{
   /* Process, parse, store or do whatever with letta. */
}
于 2012-06-20T12:57:53.247 に答える
1

EOFフラグは、の呼び出し後にのみ設定されるためfscanfです。まだ呼び出されていない場合、この条件while(!feof(fin))は意味がありません。fscanf

于 2012-06-20T12:59:28.453 に答える
0

feofファイルの終わりを超えて読み込もうとするまで、trueは返されません。次のようなファイルを想像してみてください。

これはテストです$
^

ここで^、はファイル内の現在の場所を示し、$EOFを表します。への最初の呼び出しの後fscanf(fin, "%s", letta);、ストリームは次のようになります。

これはテストです$
    ^

ループを3回繰り返した後(「is」、「a」、「test」を読み取る)、次のようになります。

これはテストです$
              ^

この時点で、文字列「test」の最後に到達したことだけがわかっているため、はfeof(fin)まだ戻り値を返します。falseしたがって、ループはもう一度実行されます。ファイルの最後にいるので、読むものがlettaないので、内容は変更されないので、「test」を2回読んだように見えます。 これでtrueが返されます feof(fin)

feof話の教訓は、ループ条件として使用してはならないということです。むしろ、次のように、読み取り操作自体の結果を使用する必要があります。

errno = 0;
while (fscanf(fin, "%s", letta) == 1)
{
  // process letta
}
if (feof(fin))
{
  printf("Reached end of file\n");
}
else
{
  perror("Error on read");
} 
于 2012-06-20T13:57:27.943 に答える