简体   繁体   中英

.eof() loop not working

I'm trying to read in numbers from a file and putting them into an array. Right now when I run the program it prints 8 numbers, then the line ends and prints the same 8 numbers. It's in a never ending loop. What am I doing wrong?

#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;                                                                   
}  

In general, don't use .eof() or .bad() . Just check the state of the stream itself

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

The eof flag will not be set if the stream fails to parse an input, and then the stream will cease to operate until the state is cleared. If you checked bad instead, it would go until it failed to parse, but would bug out at the EOF. So just check if the stream is still .good() , (which is implicit when it's in a while loop).

In your case, it's an infinite loop because the file did not open and then you are attempting to read numbers, but the reading is doing nothing because the file isn't open. Thus it never reads the eof , thus infinite loop.

I don't know what your file contains or how it would cause an infinite loop printing more than the last number. However, the eof() bit is only good for error reporting but not for loop control. Also, there is a lot of other stuff in the code which is utterly unnecessary. The following program should read the numbers OK:

#include <iostream>                                                             
#include <fstream>                                                              

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

I never saw a point in calling open() separately unless there is a conditional necessary necessary before the file name can be worked out. Likewise, calling close() explicitly seems to be pretty pointless unless you want to check that the close was successful (although I'm unsure if close() on an input stream has an opportunity to fail).

Another of my pet peeves is the unnecessary use of std::endl : this manipulator is a relatively frequent source of bad performance! It does two things:

  1. It writes an end of line character, ie \\n (or, on wide character streams the result of widening this character).
  2. It flushes the stream. On file streams this is a rather expensive operation which can easily slow down be a substantial factor (not just a few percent). The actual writes often dominate the actual real-time performances of code writing a data to a file.

Only flush the stream when you really mean to. If you feel that you need extra flushes on your stream, eg when trying to find what is written right before a crash, just set std::unitbuf on the stream object: this will be worse from a performance point of view because it flushes the stream after each insertion but it is easily removed once the problem is located.

Of course, the resulting program can be changed to something even neater like

#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"));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM