私は次のコードを持っています:
ifstream f("x.txt");
string line;
while (f.good()) {
getline(f, line);
// Use line here.
}
しかし、これは最後の行を2回読み取ります。なぜこれが発生し、どうすれば修正できますか?
非常によく似たことが起こります:
ifstream f("x.txt");
string line;
while (!f.eof()) {
getline(f, line);
// Use line here.
}
悪い、eof、および良いをチェックすることはめったにありません。特にeofの場合(!stream.eof()はよくある間違いであるため)、現在EOFにあるストリームは、必ずしも最後の入力操作が失敗したことを意味するわけではありません。逆に、EOFにないことは、最後の入力が成功したことを意味しません。
ストリーム状態関数(fail、bad、eof、good)はすべて、将来の操作の成功を予測するのではなく、ストリームの現在の状態を示します。目的の操作の後で、ストリーム自体をチェックします(これは逆フェイルチェックに相当します)。
if (getline(stream, line)) {
use(line);
}
else {
handle_error();
}
if (stream >> foo >> bar) {
use(foo, bar);
}
else {
handle_error();
}
if (!(stream >> foo)) { // operator! is overloaded for streams
throw SomeException();
}
use(foo);
すべての行を読み取って処理するには:
for (std::string line; getline(stream, line);) {
process(line);
}
指摘したように、good()は誤った名前であり、ストリーム自体をテストすることと同等ではありません(上記の例で行います)。
使用するだけ
ifstream f("x.txt");
while (getline(f, line)) {
// whatever
}
これは、そのようなループを書くための慣用的な方法です。 (Linuxマシンで)エラーを再現できませんでした。
最後の行を2回読み取らなかったが、eofに達したときに読み取れなかったため、文字列行には以前の値があります。
これは、fがEOFを読み取ろうとしているときではなく、読み取ったときに「良好」ではなくなったためです。