添加尾随空格和使用eof时的额外输出

时间:2014-02-17 23:18:32

标签: c++ ifstream eof

我正在Microsoft Visual Studio 2013下编译以下代码

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    ifstream in("filename.txt");
    int n;
    while (!in.eof()) {
        in >> n;
        cout << n << endl;
    }
    return 0;
}

filename.txt包含:

4
 

注意:第二行是空行。

我收到了这个输出:

4
4

我的问题是:当我在文件末尾添加尾随空格或空行时,为什么4在输出中重复?为什么eof在这种情况下无法正常工作?

3 个答案:

答案 0 :(得分:1)

使用!eof()!fail()!bad()!good(),总是错误的方式来调整您的输入。重点是首先执行提取 ,然后检查是否成功。如果你做前者,你几乎总能得到你遇到的问题。

从流中获取n的第一次提取4。找到换行符后,它会停止并打印n的值。当第二个循环执行时,提取器清除流中的前导空格(表示4之后的换行符),找到流的结尾并设置eofbit。由于未提取任何字符,因此还设置了failbit。当您尝试再次打印该值时,您所看到的只是上一个输入操作的结果。

这不是执行读取的正确方法。在检查流之前,您必须执行此操作。这是通常的做法:

while (in >> n)
{
    std::cout << n << std::endl;
}

执行读取后,将在流上调用operator bool(),将访问其流状态并确定提取是否成功。如果确实如此,那么循环体才会执行。

答案 1 :(得分:0)

您没有检查操作的状态。即使in >> n;设置了失败状态(因此n未设置为新值),也会执行下一行。请参阅http://www.cplusplus.com/doc/tutorial/files/http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/或类似内容。你的文件在eof之前有一个空行,所以你在while循环中运行代码两次。

答案 2 :(得分:0)

以下是上述代码执行过程中发生的事情:

1st loop iteration:
read 4 into n
output n (4)

2nd loop iteration:
read EOF
(here there is no test for EOF)
output n (4)

3rd loop iteration (doesn't happen, because EOF was read during the last read)

您应该在循环条件中测试in的状态:

while (in >> n)
{
    // all is good, carry on
}