.eof()循环不起作用

时间:2012-01-04 21:13:53

标签: c++ loops while-loop

我正在尝试从文件中读取数字并将它们放入数组中。现在,当我运行该程序时,它打印8个数字,然后该行结束并打印相同的8个数字。这是一个永无止境的循环。我做错了什么?

#include <iostream>                                                             
#include <fstream>                                                              
using namespace std;                                                            

int main()                                                                      
{                                                                               
  int num;                                                                      
  ifstream infile;                                                              
  infile.open("euler8Nums.txt");                                                
    infile >> num;//must attempt to read info prior to an eof() test            
    while(!infile.eof()){                                                       
      cout << num << endl;                                                      
      infile >> num;                                                            
    }                                                                           
    infile.close();                                                             
    return 0;                                                                   
}  

2 个答案:

答案 0 :(得分:11)

一般情况下,请勿使用.eof().bad()。只需检查流本身的状态

while (infile >> num)
    cout << num << endl;

如果流无法解析输入,则不会设置eof标志,然后流将停止运行,直到状态被清除。如果您检查了bad,那么它将一直运行直到它无法解析,但会在EOF中出错。因此,只需检查流是否仍为.good(),(当它在while循环中时是隐式的)。

在你的情况下,它是一个无限循环,因为文件没有打开然后你正在尝试读取数字,但是读取正在执行 nothing ,因为文件不是打开。因此它永远不会读取eof,因此无限循环。

答案 1 :(得分:4)

我不知道你的文件包含什么,或者它如何导致无限循环打印超过最后一个数字。但是,eof()位仅适用于错误报告,但not用于循环控制。此外,代码中还有很多其他东西是完全没必要的。以下程序应该读取数字OK:

#include <iostream>                                                             
#include <fstream>                                                              

int main()                                                                      
{                                                                               
    std::ifstream infile("euler8Nums.txt");
    for (int num; infile >> num; )
        std::cout << num << "\n";
    return 0;
}

除非在编制文件名之前有必要的条件,否则我从未看到单独调用open()的观点。同样,除非你想检查关闭是否成功(尽管我不确定输入流上的close()是否有机会失败),但显式调用close()似乎毫无意义。

我的另一个烦恼是不必要地使用std::endl:这个操纵者是一个相对频繁的糟糕表现来源!它做了两件事:

  1. 它会写一个行尾字符,即\n(或者,在宽字符流中加宽此字符的结果)。
  2. 它会刷新流。在文件流上,这是一个相当昂贵的操作,很容易减慢成为一个重要因素(不仅仅是几个百分点)。实际写入通常主导了将数据写入文件的代码的实际实时性能。
  3. 只有在你真正想要的时候才会刷新流。如果您认为自己需要额外的刷新功能,例如:在尝试查找崩溃之前写入的内容时,只需在流对象上设置std::unitbuf:从性能的角度来看,这会更糟糕,因为它会在每次插入后刷新流,但一旦出现问题就很容易删除位于。

    当然,生成的程序可以更改为更整洁的东西,如

    #include <iostream>
    #include <fstream>
    #include <algorithm>
    #include <iterator>
    
    int main()
    {
        std::copy(std::istream_iterator<int>(std::ifstream("euler8Nums.txt") >> std::ws),
                  std::istream_iterator<int>(), std::ostream_iterator<int>(std::cout, "\n"));
    }