从文本文件读取,直到EOF重复最后一行
时间:2020-03-05 18:41:52 来源:igfitidea点击:
以下C ++代码使用ifstream对象从文本文件(每行有一个数字)读取整数,直到达到EOF。为什么它在最后一行读取两次整数?如何解决这个问题?
代码:
#include <iostream> #include <fstream> using namespace std; int main() { ifstream iFile("input.txt"); // input.txt has integers, one per line while (!iFile.eof()) { int x; iFile >> x; cerr << x << endl; } return 0; }
input.txt:
10 20 30
输出:
10 20 30 30
注意:我已跳过所有错误检查代码,以使代码段较小。在Windows(Visual C ++),cygwin(gcc)和Linux(gcc)上可以看到上述行为。
解决方案
回答
只需密切关注事件链即可。
- 抢10
- 抢20
- 抢30
- 抢EOF
查看倒数第二次迭代。我们抢了30个,然后继续检查EOF。我们尚未到达EOF,因为尚未读取EOF标记(从"二进制"的角度来说,其概念位置在30行之后)。因此,我们继续进行下一个迭代。 x仍然是前一次迭代的30。现在,我们从流中读取并获得EOF。 x仍然为30,并且ios :: eofbit被引发。我们输出到stderr x(这是30,就像在上一次迭代中一样)。接下来,我们要在循环条件下检查EOF,而这次我们不在循环中。
试试这个:
while (true) { int x; iFile >> x; if( iFile.eof() ) break; cerr << x << endl; }
顺便说一句,代码中还有另一个错误。我们是否曾经尝试在一个空文件上运行它?我们得到的行为是完全相同的原因。
回答
我喜欢这个示例,目前,该示例省去了可以在while块中添加的检查:
ifstream iFile("input.txt"); // input.txt has integers, one per line int x; while (iFile >> x) { cerr << x << endl; }
不确定它有多安全...
回答
有另一种方法可以解决此问题:
#include <iterator> #include <algorithm> // ... copy(istream_iterator<int>(iFile), istream_iterator<int>(), ostream_iterator<int>(cerr, "\n"));