0

Here is the (over-simplified) code that is reading past end-of-file.

std::ifstream in_file;
in_file.open(argv[1],ios::in);

getline(in_file,line_any);
while (!in_file.eof())
    {
     record_count++;
    //:
    //: lots of stuff
    //:
    std::cout << "before getline " << line_any << "   >" << in_file.eof() << "   >" << in_file.good() << "  \n";
    getline(in_file,line_any);
    std::cout << " after getline " << line_any << "   >" << in_file.eof() << "   >" << in_file.good() << "  \n";
    }

Just before the getline(), the eof() is false and the good() is true, then the getline raises an exception. I know that I can change this to handle the exception, but why is the eof() false and the good() true?

Here is a clue. if the last line of the input file has a carriage return and line feed, then the exception happens. if the last line does not have a CRLF then there is no exception raised.

I am using the Ebarcadero 7.3 compiler.

Any and all comments are welcome.

Michael
  • 11
  • 1

1 Answers1

1

Instead of a computer reading a file, let's imagine a human reading a book. Let's make it second-personal, meaning I'll refer to this hypothetical human as "you". :)

So you are reading a book, but the book does not make a lot of sense to you. You read a page, think about it, then repeat. Now try to picture what is going on, step-by-step. You reach the end of a page, the second of the two pages you can see with the book lying flat. You think about it. It doesn't make sense. Is there more to read?

Well, if the text ended in the middle of a page (analogous to the last line not ending with an end-of-line marker), you can see that the text has ended. However, if the text went all the way to the end of the page, how do you know if there is text on the next page until you turn the page? This book happens to have several blank pages at its end, so simply looking at the thickness of what is left is inconclusive. There is no "The End" or other mark indicating the end of the book; the text simply ends once it reaches its conclusion. And you do not understand the meaning well enough to recognize the conclusion.

This is close to what getline does. You read to the end of the page; getline reads to the end-of-line marker. Neither you nor getline has any way to comprehend what you read, so you cannot guess if the text has finished based solely upon what was read. In order to see if there is more to read, you had to turn to the next page. In order to see if there is more to read, getline had to go to the next line. If the book ends at the end of a page, you cannot announce that you are done reading until you try to read something that is not there. If the file ends at the end of a line, getline cannot announce that it is done reading until it tries to read something that is not there.

So, correct. If all of your lines have end-of-line markers, then you will face a situation where there is no indication that you are at the end of the file until you try to read past the end of the file. The flags tell you that before trying to read past the end of the file, the stream is in good condition and the end of the file has not yet been seen. You might be at the end of the file, but that remains to be seen.

Yes, it would have been possible to implement the reading a different way. However, looking ahead is extra overhead that the language designers did not want to force on getline.

JaMiT
  • 9,693
  • 2
  • 12
  • 26