以下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)上可以看到上述行为。

===============>>#1 票数:120 已采纳

只需密切关注事件链。

  • 抢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;
}

顺便说一句,您的代码中还有另一个错误。 您是否曾经尝试在空文件上运行它? 您得到的行为是完全相同的原因。

===============>>#2 票数:34

我喜欢这个示例,该示例目前不包含可以在while块中添加的检查:

ifstream iFile("input.txt");        // input.txt has integers, one per line
int x;

while (iFile >> x) 
{
    cerr << x << endl;
}

不确定它有多安全...

===============>>#3 票数:15

还有另一种方法:

#include <iterator>
#include <algorithm>

// ...

    copy(istream_iterator<int>(iFile), istream_iterator<int>(),
         ostream_iterator<int>(cerr, "\n"));

===============>>#4 票数:5

如果不对原始代码进行太多修改,它可能变成:

while (!iFile.eof())
{  
    int x;
    iFile >> x;
    if (!iFile.eof()) break;
    cerr << x << endl;
}

但总体而言,我更喜欢上述两种其他解决方案。

===============>>#5 票数:5

EOF模式需要主要读取才能“引导” EOF检查过程。 考虑到在第一次读取之前,空文件最初不会设置其EOF。 在这种情况下,主要读取将捕获EOF,并完全跳过循环。

这里需要记住的是,直到第一次尝试读取文件的可用数据之前,您都不会获得EOF。 读取确切的数据量不会标记EOF。

我应该指出,如果文件为空,则将打印给定的代码,因为EOF将阻止在进入循环时将值设置为x。

  • 0

因此,添加一个主读取并将循环的读取移到末尾:

int x;

iFile >> x; // prime read here
while (!iFile.eof()) {
    cerr << x << endl;
    iFile >> x;
}

===============>>#6 票数:2

int x;
ifile >> x

while (!iFile.eof())
{  
    cerr << x << endl;        
    iFile >> x;      
}

===============>>#7 票数:2

在最后一行的末尾,您有一个换行符,>>运算符不会读取它,也不是文件的末尾。 请进行实验并删除新行(文件中的最后一个字符)-您将不会得到重复。 要拥有灵活的代码并避免不良影响,只需应用其他用户提供的任何解决方案。

  ask by Ashwin Nanjappa translate from so

未解决问题?本站智能推荐: