5

Example why stream :: good is Wrong?

 3 years ago
source link: https://www.codesd.com/item/example-why-stream-good-is-wrong.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Example why stream :: good is Wrong?

advertisements

I gave an answer which I wanted to check the validity of stream each time through a loop here.

My original code used good and looked similar to this:

ifstream foo("foo.txt");

while (foo.good()){
    string bar;
    getline(foo, bar);
    cout << bar << endl;
}

I was immediately pointed here and told to never test good. Clearly this is something I haven't understood but I want to be doing my file I/O correctly.

I tested my code out with several examples and couldn't make the good-testing code fail.

First (this printed correctly, ending with a new line):

bleck 1
blee 1 2
blah
ends in new line

Second (this printed correctly, ending in with the last line):

bleck 1
blee 1 2
blah
this doesn't end in a new line

Third was an empty file (this printed correctly, a single newline.)

Fourth was a missing file (this correctly printed nothing.)

Can someone help me with an example that demonstrates why good-testing shouldn't be done?


They were wrong. The mantra is 'never test .eof()'.

  • Why is iostream::eof inside a loop condition considered wrong?

Even that mantra is overboard, because both are useful to diagnose the state of the stream after an extraction failed.

So the mantra should be more like

Don't use good() or eof() to detect eof before you try to read any further

Same for fail(), and bad()

Of course stream.good can be usefully employed before using a stream (e.g. in case the stream is a filestream which has not been successfully opened)

However, both are very very very often abused to detect the end of input, and that's not how it works.


A canonical example of why you shouldn't use this method:

std::istringstream stream("a");
char ch;
if (stream >> ch) {
   std::cout << "At eof? " << std::boolalpha << stream.eof() << "\n";
   std::cout << "good? " << std::boolalpha << stream.good() << "\n";
}

Prints

false
true

See it Live On Coliru


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK