getline questions

M

Mark P

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?

Thanks for your help,
Mark
 
B

Bob

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?

If the function extracts no characters, it calls
is.setstate(ios_base::failbit) which may throw ios_base::failure.

In case F2.a, the read has resulted in extraction of characters. So
the file stream is still true or good.

In F1.b, no characters are extracted. The read has failed, so the
stream is set to fail or false.
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?

In F1.b a sentry object is created because the file stream is still
true. Since the sentry object is true, it calls string::erase on the
passed string. So the string is erased.

In F2.a, the sentry object is false because the file stream is false.
So the passed string is not erased. It continues to contain the same
string as the previous call.

The sentry object performs some preliminary and cleanup work for the
stream.

Best wishes,

Bob
 
?

=?ISO-8859-1?Q?Klaus_F=FCller?=

Mark said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,690
Latest member
MacGyver

Latest Threads

Top