ただし、C ++プログラマは、最後の行が2回読み取られるまで、cin.eof()が「true」を返さないことが常に発生することに注意しています。
それは起こっていることではありません。eofbitブール値に変換しないで役割を果たしている(stream::operator bool(またはoperator void*古いC ++の))。のみbadbitとfailbit関与しています。
空白で区切られた数値を含むファイルを読んでいるとします。ループに基づくループcin.eof()は必然的に間違っているか、ifテストで一杯になります。あなたはEOFまで読んでいない。あなたは数字を読んでいます。したがって、コードにそのロジックを表現させます。
while (stream >> some_var) {
process_value(some_var);
}
これは、ファイルの最後の行が末尾で終わるか、0 42\nまたは0 42(ファイルの最後の行の末尾に新しい行がない)かどうかに関係なく機能します。ファイルがで終わる場合、0 42\n最後の正常な読み取りは値42を取得し、その最後の行末マーカーを読み取ります。EOFマーカーはまだ読み取られていないことに注意してください。関数process_valueはで呼び出され42ます。ストリーム抽出演算子>>次の呼び出しは、EOFを読み、何も以来、抽出された、両方eofbitとfailbit設定されます。
一方、ファイルが0 42(最後の行の終わりに改行がない)で終わっているとします。最後の正常な読み取りは、EOFマーカーで終了する値42を取得します。おそらく、42を処理する必要があります。これがeofbit、入力ストリームのブール変換演算子でが機能しない理由です。ストリーム抽出演算子への次の呼び出し>>で、基盤となる機械は、eofbitが既に設定されていることをすばやく確認します。これにより、すぐにが設定されますfailbit。
最初のコードが常に正しく機能しないのはなぜですか?
ループ条件としてEOFをチェックするべきではないからです。ループ条件は、たとえば、ストリームから数値を抽出するなど、実行しようとしていることを表す必要があります。