Sunday 14 January 2018

c++ - Testing stream.good() or !stream.eof() reads last line twice













I
have the following piece of
code:



ifstream
f("x.txt");
string line;
while (f.good()) {
getline(f,
line);

// Use line
here.
}


But
this reads the last line twice. Why does this happen and how do I fix
it?



Something very similar happens
with:



ifstream
f("x.txt");
string line;

while (!f.eof()) {

getline(f, line);
// Use line
here.
}

class="post-text" itemprop="text">
class="normal">Answer



You very,
very rarely want to check bad, eof, and good. In particular for eof (as !stream.eof() is
a common mistake), the stream currently being at EOF does not necessarily mean the last
input operation failed; conversely, not being at EOF does not mean the last input was
successful.



All of the stream state functions –
fail, bad, eof, and good – tell you the current state of the stream rather than
predicting the success of a future operation. Check the stream itself (which is
equivalent to an inverted fail check) after the desired
operation:




if
(getline(stream, line)) {
use(line);
}
else {

handle_error();
}

if (stream >> foo >> bar)
{
use(foo, bar);
}

else {

handle_error();
}

if (!(stream >> foo)) { //
operator! is overloaded for streams
throw
SomeException();
}
use(foo);



To
read and process all lines:



for
(std::string line; getline(stream, line);) {

process(line);
}


Pointedly,
good() is misnamed and is not equivalent to testing the stream itself (which the above
examples do).


No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...