为什么in.good()与!in.fail()不一样?

时间:2015-09-27 02:20:31

标签: c++

我读过以下是反模式:

while(in.good()) {
    // ...
}

但这是首选:

while(operation) {
}

但是,该流有一个转换运算符bool返回!fail()!fail()good()不一样吗?如果没有,为什么这两个函数不对称?我希望它与true == !false类似。

3 个答案:

答案 0 :(得分:2)

http://en.cppreference.com/w/cpp/io/basic_ios/good处有一个很好的表格,可以解释std::istream的状态以及各种函数返回的值。

唯一的时间while ( stream.good() )while(stream)将是成功读取流内容并达到EOF的时间。那时,stream.good()返回true,而(bool)stream评估为false.

答案 1 :(得分:2)

如果先前的读取操作成功而未遇到EOF,则

in.good()为真。 (即使读取操作成功,也可能遇到EOF。)因此,如果in.good()为假,则先前的读取操作失败 - 在这种情况下,下一个操作也将失败 - 或者EOF是遇到 - 在这种情况下,下一个读操作也将失败。因此,如果in.good()为false,则下一次读取操作肯定会失败。如果我们想知道是否值得尝试执行读操作,我们应该测试in.good()

in.good()为真的事实并不能保证任何事情。假设in以空格结尾,这通常就是这种情况,因为文本文件需要以换行结束。格式化的读取操作在第一个空格字符处停止,并unget将其返回到输入流中,因此如果先前的读取操作读取最后一个数据项,则它仍然不会将流保留在EOF,并且{{1} }仍然是in。 [见注1]。所以如果你的循环看起来像这样:

good

然后你不会注意到最后一个while (in.good()) { in >> x; /* Do something with x assuming that it is valid */ } 失败了,你最后会在最后一个循环中使用未定义的in >> x值。 (可能最后一个值将被处理两次。)

如果您的循环为xwhile (!in.bad()),则会发生同样的事情。

您真正想要的是检查while (!in.eof())是否成功。没有其他的。而经典的方法是:

in >> x

while (in >> x) { /* If we get here, x has a legitimate value */ ... } 只返回in >> x,因此完全等同于

in

换句话说,while (in >> x, in) { /* ... */ } 正好是前一个操作失败的bool(in),而false恰好是成功的时候。这与true不同,因为我们还不想测试是否遇到EOF。

注意:

  1. 如第一段所述,读取成功并设置EOF 可能。可能发生的一种方法是文件不以换行符结尾。这很罕见,但你不应该排除它。它可能发生的事实恰恰是in.good()没有检查eof标志的原因:in.bad()为false肯定意味着先前的读取操作失败。

答案 2 :(得分:0)

in.good()等于:[ios documentation]

! ( in.eof() || in.fail() || in.bad() )