Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resetting the State of a Stream

I have a question which is slightly similar to this question on stackoverflow std::cin.clear() fails to restore input stream in a good state, but the answer provided there does not work for me.

The question is: how can I reset the state of a stream to 'good' again?

Here is my code how I try it, but the state is never set to good again. I used both of the lines ignore separately.

int _tmain(int argc, _TCHAR* argv[])
{
    int result;
    while ( std::cin.good() )
    {
        std::cout << "Choose a number: ";
        std::cin >> result;

        // Check if input is valid
        if (std::cin.bad())
        {
            throw std::runtime_error("IO stream corrupted");
        }
        else if (std::cin.fail())
        {
            std::cerr << "Invalid input: input must be a number." << std::endl;
            std::cin.clear(std::istream::failbit);
            std::cin.ignore();
            std::cin.ignore(INT_MAX,'\n');
            continue;
        }
        else
        {
            std::cout << "You input the number: " << result << std::endl;
        }
    }
    return 0;
}
like image 934
physicalattraction Avatar asked Jun 28 '12 14:06

physicalattraction


1 Answers

The code here

std::cin.clear(std::istream::failbit);

doesn't actually clear the failbit, it replaces the current state of the stream with failbit.

To clear all the bits, just call clear().


The description in the standard is a bit convoluted, stated as the result of other functions

void clear(iostate state = goodbit);

Postcondition: If rdbuf()!=0 then state == rdstate(); otherwise rdstate()==(state | ios_base::badbit).

Which basically means that the next call to rdstate() will return the value passed to clear(). Except when there are some other problems, in which case you might get a badbit as well.

Also, goodbit actually isn't a bit at all, but has the value zero to clear out all the other bits.

To clear just the one specific bit, you can use this call

cin.clear(cin.rdstate() & ~ios::failbit);

However, if you clear one flag and others remain, you still cannot read from the stream. So this use is rather limited.

like image 67
Bo Persson Avatar answered Nov 04 '22 11:11

Bo Persson