以下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

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

5回复

如何一次读取一行或整个文本文件?

我在一个介绍文件的教程中(如何从\\到文件读取和写入) 首先,这不是一个功课,这只是我正在寻求的一般帮助。 我知道如何一次读一个单词,但我不知道如何一次读一行或如何读取整个文本文件。 如果我的文件包含1000个单词怎么办? 阅读每个单词是不切实际的。 我的名为(Read
1回复

将tabify应用于文本文件会导致文件读取器出现段错误

我有一个包含以下文本的文件records.txt : 我已经由Mike麦格拉思复制从C ++编程下面的代码到一个文件format.cpp读取数据records.txt : 现在,在我的.emacs文件中,我可以使用以下命令将制表符自动转换为所有文件中的空格: 因此,当我编
1回复

文本文件问题(Visual C ++)

我正在尝试使程序提示用户输入文件名,然后提示用户输入要删除的单词。 有没有没有在main外部进行任何功能的方法? (预先感谢!)到目前为止,这是我的代码:
2回复

从文本文件中的列确定最低和最高值(c ++)[关闭]

我已经在这个项目上工作了一段时间,或者更确切地说,我一直在努力寻找如何在这个项目上工作一段时间。 总的来说,我是编程的一个新手(可能从c ++开始是一个巨大的错误,但无论如何),因此请记住这一点。 我有一个看起来像这样的文本文件: http : //pastebin.com/19Bbg1
6回复

如何在C ++中将变量声明为文本文件的double值输出

我是C ++的新手,我想知道如何将声明为double的变量输出/写入txt文件。 我知道如何使用fstream输出字符串,但是我无法弄清楚如何发送其他内容。 我开始认为您只能将字符串发送到文本文件,这是正确的吗? 如果是这样,那么您将如何将存储在变量中的信息转换为字符串变量? 这是我
2回复

如何将包含数字的文本文件转换为二进制文件?

所以我创建了一个使用ifstream打开文本文件的程序。 现在我想让它以二进制形式输出这个文件。 我尝试过ofstream并使用.write(),但是当我执行程序崩溃时。 当我在网上看到使用.write()时,我正确设置了它,但我没有看到有人用我正在使用的东西做。 有人有解决方案吗?
2回复

从C ++中的地图中删除文本文件的单词而无需循环

我尝试进行设置以存储文本文件的某些单词。 然后,我想从已经组成的地图中删除这些单词。 我已经成功建立了一个存储这些单词的集合,但是我无法从地图上将其删除。 此外,我不能使用循环语句(如for循环或while循环)。
1回复

该文件设置正确,但eof()和peek()意外地从新流返回错误的值

我想生成一个随机数组。 我想将它们保存到一个单独的文件中。 之后我想读取刚保存的数据并在新功能中实现它们。 完全不知道为什么fin.peek()和fin.eof()的值分别变为-1和1。 当我运行这两个功能时,控制台告诉我这一点。 我还提供了一些其他的测试,例
3回复

如何从fstream精确地读取128个字节到字符串对象? [重复]

这个问题已经在这里有了答案: 直接从std :: istream读取到std :: string 6个答案 如何将fstream中的128个字节准确地读入字符串对象? 我编写了一些代码来读取文件的前128个字节并打印,然后读取文件的后128个字节并打印。 最
3回复

设置EOF标志后无法使fstream寻回0

因此,我已经从文件中读取了这个fstream,并且在设置EOF标志后尝试从文件中读取时出现了这个疯狂的错误(或者至少是我认为的那样)。 这是我的问题的范围: 我添加了整数“ test”,以便可以跟踪调试器中流的位置。 现在,我在调试器中看到的是,即使程序进入“ if”并清除了fs