ただし、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をチェックするべきではないからです。ループ条件は、たとえば、ストリームから数値を抽出するなど、実行しようとしていることを表す必要があります。