下面的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
注释:我跳过了所有的错误检查代码,以保持代码片段较小。上述行为在视窗(Visual C++)、cygwin (gcc)和Linux (gcc)上都可以看到。
发布于 2008-08-22 02:50:56
只需密切关注事件链即可。
<代码>F29
看看倒数第二次迭代。你抓取了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;
}
顺便说一下,您的代码中还有另一个bug。你有没有试过在一个空文件上运行它?你得到的行为也是出于同样的原因。
发布于 2008-08-22 02:59:25
我喜欢这个示例,就目前而言,它省略了您可以在while块中添加的check:
ifstream iFile("input.txt"); // input.txt has integers, one per line
int x;
while (iFile >> x)
{
cerr << x << endl;
}
不确定它有多安全...
发布于 2008-08-22 04:46:34
有另一种方法可以解决这个问题:
#include <iterator>
#include <algorithm>
// ...
copy(istream_iterator<int>(iFile), istream_iterator<int>(),
ostream_iterator<int>(cerr, "\n"));
https://stackoverflow.com/questions/21647
复制相似问题