我读过以下是反模式:
while(in.good()) {
// ...
}
但这是首选:
while(operation) {
}
但是,该流有一个转换运算符bool返回!fail()
。 !fail()
与good()
不一样吗?如果没有,为什么这两个函数不对称?我希望它与true == !false
类似。
答案 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)
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
值。 (可能最后一个值将被处理两次。)
如果您的循环为x
或while (!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。
in.good()
没有检查eof标志的原因:in.bad()
为false肯定意味着先前的读取操作失败。答案 2 :(得分:0)
in.good()等于:[ios documentation]
! ( in.eof() || in.fail() || in.bad() )