提问人:Prabhu 提问时间:12/1/2010 最后编辑:CommunityPrabhu 更新时间:2/27/2013 访问量:31320
测试 stream.good() 或 !stream.eof() 读取最后一行两次 [duplicate]
Testing stream.good() or !stream.eof() reads last line twice [duplicate]
问:
可能的重复:为什么循环条件中的 iostream::
eof 被认为是错误的?
我有以下一段代码:
ifstream f("x.txt");
string line;
while (f.good()) {
getline(f, line);
// Use line here.
}
但这会读最后一行两次。为什么会发生这种情况,我该如何解决?
非常相似的情况发生:
ifstream f("x.txt");
string line;
while (!f.eof()) {
getline(f, line);
// Use line here.
}
答:
9赞
Fred Foo
12/1/2010
#1
只需使用
ifstream f("x.txt");
while (getline(f, line)) {
// whatever
}
这是编写此类循环的惯用方式。我无法重现该错误(在 Linux 机器上)。
评论
0赞
Aaron McDaid
5/20/2011
我刚刚意识到为什么会这样:如果最后一行末尾没有换行符,那么最后一次成功调用 getline() 可能会设置 eof。仅当对 getline() 的调用不成功时,才会设置失败位。因此,我们不想在 eof 结束循环,但我们确实希望在失败时结束它。
0赞
Aaron McDaid
5/20/2011
还有一件事..我一直在做.我认为这是正确的吗?但我以后会用你的答案。while(f.peek() != EOF) { ... }
3赞
CashCow
12/1/2010
#2
它没有读取最后一行两次,但由于它在到达 eof 时无法读取,因此您的字符串行具有之前的值。
这是因为 f 在读取 EOF 时不再是“好”的,而不是在将要读取它时。
34赞
Fred Nurk
12/1/2010
#3
你很少想检查坏的、eof的和好的。特别是对于 eof(因为 !stream.eof() 是一个常见的错误),当前处于 EOF 的流并不一定意味着最后一个输入操作失败;相反,不在EOF并不意味着最后一个输入是成功的。
所有流状态函数(失败、坏、EOF 和良好)都会告诉您流的当前状态,而不是预测未来操作的成功。在所需操作后检查流本身(相当于反向失败检查):
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() 被错误地命名了,并不等同于测试流本身(上面的例子就是这样做的)。
评论
0赞
KeithB
12/1/2010
关于检查 eof 的部分是正确的,但检查流本身的建议有点偏离。 表示未设置 EOFBIT、Badbit 或 FAILBIT。 表示设置了 Badbit 或 Failbit。检查流(使用 void* 转换或运算符 !)与调用 fail() 成员函数完全相同。good()
fail()
2赞
Fred Nurk
12/1/2010
@KeithB:你可能会注意到,我把失败排除在“应该很少检查”的组之外。失败的流很重要,检查流本身几乎总是比等效的 fail() 更方便。将 getline(stream, line) 与 !getline(stream, line).fail() 进行比较。
下一个:你能解释一的概念吗?
评论
.good()
.eof()
.fail()
getline
>>