Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading from text file until EOF repeats last line [duplicate]

People also ask

What is EOF in C++ with example?

C++ provides a special function, eof( ), that returns nonzero (meaning TRUE) when there are no more data to be read from an input file stream, and zero (meaning FALSE) otherwise.

What is CIN EOF?

cin. eof() test if the stream has reached end of file which happens if you type something like Ctrl+C (on Windows), or if input has been redirected to a file etc.

How do I use end of file in C++?

You can detect when the end of the file is reached by using the member function eof() which has prototype : int eof(); It returns non-zero when the end of file has been reached, otherwise it returns zero.


Just follow closely the chain of events.

  • Grab 10
  • Grab 20
  • Grab 30
  • Grab EOF

Look at the second-to-last iteration. You grabbed 30, then carried on to check for EOF. You haven't reached EOF because the EOF mark hasn't been read yet ("binarically" speaking, its conceptual location is just after the 30 line). Therefore you carry on to the next iteration. x is still 30 from previous iteration. Now you read from the stream and you get EOF. x remains 30 and the ios::eofbit is raised. You output to stderr x (which is 30, just like in the previous iteration). Next you check for EOF in the loop condition, and this time you're out of the loop.

Try this:

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

By the way, there is another bug in your code. Did you ever try to run it on an empty file? The behaviour you get is for the exact same reason.


I like this example, which for now, leaves out the check which you could add inside the while block:

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

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

Not sure how safe it is...


There's an alternative approach to this:

#include <iterator>
#include <algorithm>

// ...

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

Without to much modifications of the original code, it could become :

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

but I prefer the two other solutions above in general.