Wednesday, 24 January 2018

c++ - Reading from text file until EOF repeats last line




The following C++ code uses a ifstream object to read integers from a text file (which has one number per line) until it hits EOF. Why does it read the integer on the last line twice? How to fix this?




Code:



#include 
#include
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


Output:




10  
20
30
30


Note: I've skipped all error checking code to keep the code snippet small. The above behaviour is seen on Windows (Visual C++), cygwin (gcc) and Linux (gcc).


Answer



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.


No comments:

Post a Comment

casting - Why wasn&#39;t Tobey Maguire in The Amazing Spider-Man? - Movies &amp; TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...