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