web-dev-qa-db-ja.com

eof()の悪い習慣?

重複の可能性:
ループ条件内のiostream :: eofが間違っていると見なされるのはなぜですか?

そのため、ファイル入力を必要とする多くのプログラムでeof()関数を使用してきました。教授は、使用しても問題ないと言っていましたが、SO =理由を明記せずに使うべきではないと言っていたので、疑問に思っていたのですが、正当な理由はありますか?

25
Sam

eofを使用して、レポートが報告する正確な状態をテストできます-あなたがファイルの終わりを超えて読み取ろうとしたかどうか。これを使用して、読み取る入力が多いかどうか、または読み取りが成功したかどうかをテストすることはできません。これは、より一般的なテストです。

違う:

while (!cin.eof()) {
  cin >> foo;
}

正しい:

if (!(cin >> foo)) {
  if (cin.eof()) {
    cout << "read failed due to EOF\n";
  } else {
    cout << "read failed due to something other than EOF\n";
  }
}
34
Erik

別の理由で入力が失敗した場合、ねじ込まれる可能性があるため、使用しないでください。

while(!file.eof()) {
    int i;
    file >> i;
    doSomething(i);
}

ファイルの内容が「WHAARRRRRRGARBL」の場合、上記のループはどうなりますか?ファイルの終わりではないため、無限にループしますが、それでもintを抽出することはできません。

12
Puppy

上記の回答が紛らわしい場合:

人々がそれが間違っていると思うこと:

  • eof()は、読み取った最後の部分にファイルの最後のバイトが含まれているかどうかを確認しません。
  • 次のバイトがファイルの終わりの後であるかどうかを確認することはできません。

実際に何をするか:

  • eof()は、最後の読み取りにファイルの終わりを超えたバイトが含まれていたかどうかを報告します。

Eof()がtrueの場合、すでに間違いを犯しています。したがって、教授の声明を説明します。エラーが発生したという意味で使用してください。

3
Lee Louviere

どのように使用していますか? .eof()が通知するのは、ストリームがすでにファイルの終わりに達しており、そこにないデータを読み取ろうとしたことです。

これは通常あなたが望むものではありません。通常、ファイルの終わりに到達していること、またはファイルの終わりに到達しようとしていることを知りたいのですが、すでにファイルの終わりに到達しているわけではありません。次のようなループで:

_while(!f.eof())
{
    f >> /* something */;
    /* do stuff */
}
_

入力を読み込んで失敗し、次に_/* do stuff */_ですべてを実行しようとすると、ループ条件が失敗し、ループが停止します。

そのループのもう1つの問題は、入力が失敗する可能性がある他の方法があることです。 EOFではないファイルにエラー条件がある場合、.fail()trueを返しますが、.eof()は返しません。

3
David Thornley