Mark P schrieb:
Quote:
Consider the following snippet of code to read lines from a text file:
>
ifstream file_stream( "some_file.txt");
string read_line;
while( file_stream)
{
getline( file_stream, read_line);
}
>
I've tried this on two text files, one whose last line concluded with a
newline character (F1) and one whose last line did not conclude with a
newline character (F2). Then I look at the file_stream.eof() and (bool)
file_stream at various points in the reading process.
>
For F1 (final newline), I observe:
a. After reading the last line of text, eof() is false, and file_stream
is true.
b. After one more getline, eof() is true, file_stream is false, and
read_line is empty.
>
For F2 (no final newline), I observe:
a. After reading the last line of text, eof() is true, and file_stream
is true.
b. After one more getline, eof() is true, file_stream is false, and
read_line is the same as it was in the previous call (i.e., the last
line of text of the file).
>
So now I'm trying to make sense of all this and I have a couple questions:
>
1. Comparing F1.b. to F2.a., why is file_stream false in the first case
and true in the second case? We've hit the EOF in both cases-- is it
because in the latter we read some characters first?
>
2. Comparing F1.b. to F2.b., why is read_line empty in the first case
and unchanged from the previous value in the second case?
Your "why?" has several aspects. There are technical reasons for the
behaviur you observed buried within the libraries. At the other hand
there are intended usages:
Always use 'file_stream' (e.g. the boolean value of the file-descriptor)
to check if data was retreived or if (otherwise) "something went wrong".
_If_ "something went wrong" (e.g. file_stream is false) the contents of
'read_line' has no real meaning: nothing has been read. To avoid
uninitialized variables the library returns an empty string in
'read_line' or what ever.
_After_ "something went wrong" (e.g. file_stream is false) you check for
EOF. As 'getline' returns the stream itsself the _idiom_ for the whole
loop is:
while( getline(file_stream, read_line) ) {
<Work on read_line>
}
if( !file_stream.eof() ) {
<Do further research on cause of error and ...>
<... possibly throw an exception>
}
// No 'else' if you threw an exception
<Go on>
You simply don't 'file_stream.eof()' before '(! file_stream)' and you
don't access 'read_line' after.
kf