Home > Software engineering >  Difference between "ins" and "ins.good()" when passed in a while loop condition
Difference between "ins" and "ins.good()" when passed in a while loop condition

Time:03-21

Given the following code:

int main(){
    ifstream ins;
    ins.open("infile.txt");
    int i = 0;
    int x = 0;
    while (ins) {
        ins >> x;
        cout << i;
        i  ;
    }
    ins.close();
}

Assume infile.txt contains:

1 2 3

What's the difference between the current while loop condition, and if the while loop condition is "ins.good()" instead?

I assumed they were the same thing until I inputted it to my IDE, where the code outputted 0123 when I passed ins, and 012 when passing ins.good().

I've been trying to figure this out for a while, but got nowhere.

Thank you so much!

CodePudding user response:

The difference is that in this expression

while (ins) {

there is used the operator

explicit operator bool() const;

It returns the value of the expression !fail(). fail returns true if failbit or badbit is set in rdstate(). Pay attention to that eofbit is not checked.

On the other hand, the member function good returns true when rdstate() == 0 and false otherwise that is in particular when eofbit is set,

CodePudding user response:

The expression ins will cause ins.operator bool() to be called, which is equivalent to !ins.fail().

The difference between ins.operator bool() and ins.good() is the behavior when the eofbit is set. When the eofbit is set, but all other bits are clear, then operator bool() will return true, whereas good() will return false.

See the documentation of these two functions for further information:

std::basic_ios::operator bool
std::basic_ios::good

Your loop is wrong:

while (ins) {
    ins >> x;
    cout << i;
    i  ;
}

In your code above, you are checking the state of the input stream before attempting to performing the input. You should do it the other way around. You should check the state of the input stream after attempting to perform the input, in order to check whether an error occurred in that attempt, especially if you intend to use the result of the input attempt (which you do not do in your posted code). See this question for more information:

Why is iostream::eof inside a loop condition (i.e. while (!stream.eof())) considered wrong?

For the reason stated above, you should change your loop to the following:

while ( ins >> x ) {
    cout << i;
    i  ;
}
  • Related