我正在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
在这种情况下无法正常工作?
答案 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
}