为什么(foobar>>x)比(!foobar.eof())更受欢迎?

9

可能是重复问题:
为什么在循环条件中使用iostream::eof被认为是错误的?
eof()是不好的实践吗?

我的老师说我们不应该使用EOF来读取文本文件或二进制文件信息,而是应该使用(afile>>x)这种方式。他没有解释原因,有人能解释一下吗?还能有人解释一下这两种不同读取方法的区别吗?

//Assuming declaration 
//ifstream foobar



( ! foobar.eof() )
{
    foobar>>x; // This is discouraged by my teacher

}


 while (foobar>>x)
{
  //This is encouraged by my teacher

}

这个和许多其他问题一样,都是关于 ifstream 的。它似乎无法正确读取文件末尾的 EOF 字符。 - Rapptz
1个回答

15

因为文件在读取之前不在结尾。

operator>> 返回一个对流的引用,该流处于读取尝试后的状态(无论成功或失败),如果成功,则该流评估为true;如果失败,则评估为false。如果首先测试 eof(),那么文件可能没有有用的数据,但还没有到达EOF,当你从中读取时,它就在EOF位置,读取将失败。

另一个重要细节是,流的 operator>> 跳过所有前导空格,而不是后面的空格。这就是为什么文件在读取之前不能在EOF上,并且在读取后可以在EOF上的原因。

此外,前者在文件中下一个数据不能读入一个整数时也会起作用(例如,下一个数据是x),而不仅仅是在EOF时,这非常重要。

示例:

考虑以下代码:

int x, y;

f >> x;

if (!f.eof())
    f >> y;

假设f是一个包含数据123␣(其中␣表示空格)的文件,第一次读取将成功,但之后文件中没有更多的整数并且它 不是在EOF。第二次读取将失败并且文件将处于EOF状态,但你不知道因为你在尝试读取之前测试了EOF。然后你的代码继续导致未定义的行为,因为y未初始化。


1
@Computernerd 看看我的例子。 - Seth Carnegie
我喜欢你的解释。它直截了当,易于理解。 - paddy
@SethCarnegie 如果使用 while ( f>>y ),它也会因为无法读取空格而导致失败吗? - Computernerd
@Computernerd 就像我之前说的那样,operator>> 返回一个 ostream&,它会被评估为一个 bool。如果读取失败,它将被评估为 false,如果成功,则将被评估为 true - Seth Carnegie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接