Search code examples
c++while-loopifstream

Behavior of fstream as a bool and fstream.good() function


I recently used fstream for a homework assignment and I was wondering about how two things worked.

#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char** argv) {

    ifstream myFile;
    myFile.open("fileone.txt");
    int myInt = 0;

    while (myFile.good()) { // What is the difference between myFile and myFile.good()?
        if (!myFile.eof()){
            myFile >> myInt;
            cout << myInt << endl;
        }
    }

    return 0;
}

This is a snippet of my actual code I am working on. In another post, someone said that if I used while(myFile) , it would automatically convert into a bool. What is the difference between using this and using the member function .good() of the ifstream class? I know that .good() breaks out of the while loop when I reach the end of the text file but how does using the stream name behave?


Solution

  • IOStream classes have 4 functions for assessing the stream state: good(), bad(), fail(), and eof(). Excluding good(), each function checks a single bit in the underlying stream state and returns whether or not the bit is on (are there errors?). good() in particular checks if all the bits are off (is the stream valid?). These are what they are for:

    • good(): The stream has not encountered an error.
    • bad(): The stream has encountered an error that effects the integrity of the stream (i.e memory allocation failure, no buffer, etc.)
    • fail(): Typically a recoverable error (formatting/parsing failure).
    • eof(): The end-of-file (EOF) character has been reached.

    When performing I/O, it is integral that you check for errors in the stream while processing input. What novices typically don't know is that the only function that was meant to be used to check for valid input is fail(). All the other functions are useful in other cases but not for conditioning input.

    Futhermore, novices also fail to realize that input must be performed before checking for errors. Doing otherwise allows an unchecked extraction, allowing the body of the loop to access the value that was not produced from a valid extraction.

    Streams have a boolean operator that returns !fail(), this allows you to check the stream in an elegant way after performing input, like this:

    while (myFile >> myInt) {
        // ...
    }
    

    This is the best way to perform input. The extraction itself should be present within a conditional context so that the body of whatever its being used in is executed only if the extraction succeeded.