fms
fms

Reputation: 2187

Why the following c++ code keeps output "bad data, try again"?

int main()
{
        int temp;
        while (cin>>temp, !cin.eof())
        {
                if (cin.bad())
                {
                        throw runtime_error("IO stream corrupted");
                }

                if (cin.fail())
                {
                        cerr<<"bad data, try again";
                        cin.clear(istream::failbit);
                        continue;
                }
        }

        return 0;
}

If I input x then Enter,the output will be :

, try againbad data, try againbad data, try a a, try againbad data, try againbad data, try ta, try againbad data, try againbad data, try ata, try againbad data, try againbad data, tr data, try againbad data, try againbad data, t

Why?

Upvotes: 2

Views: 395

Answers (6)

Fr&#233;d&#233;ric Hamidi
Fr&#233;d&#233;ric Hamidi

Reputation: 263047

The ios::clear() method actually replaces the stream control state bits with its argument. You're setting cin's control state to fail every time you issue cin.clear(istream::failbit);.

You should simply call cin.clear(); instead, without arguments. That will reset the stream's control state to good.

EDIT: Oh my god, I forgot.

You also need to call istream::ignore() to discard the invalid x token you've just entered, since clear() doesn't flush pending input:

if (cin.fail()) {
    cerr << "bad data, try again\n";
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    continue;
}

Upvotes: 5

johnhforrest
johnhforrest

Reputation: 991

This has to do with data still being in the input buffer. cin.clear() is simply clearing the error state of cin rather than clearing the buffer. Try doing something like this:

int main()
{
        int temp;
        while (cin>>temp, !cin.eof())
        {
                if (cin.bad())
                {
                        throw runtime_error("IO stream corrupted");
                }

                if (cin.fail())
                {
                        cerr<<"bad data, try again";
                        cin.clear();
                        cin.sync();
                        continue;
                }
        }

        return 0;
}

cin.sync() will effectively clear the buffer for you. See http://www.cplusplus.com/reference/iostream/istream/sync/ for more information on it.

Upvotes: 1

Armen Tsirunyan
Armen Tsirunyan

Reputation: 133064

Because your loop will end only when end-of-file is reached. But if you try to read a number where there is an alpha character, cin will fail but eof will never be reached. It will fail to read the number over and over again.

Upvotes: 0

lijie
lijie

Reputation: 4871

Because x is not an integer, the operator>> operator doesn't read anything, so when you clear the bit and try again, the same thing results.

Upvotes: 3

Puppy
Puppy

Reputation: 146968

You didn't clear() the stream.

Upvotes: 2

frast
frast

Reputation: 2740

If you use formatted input/output the data must match. x is not an integer. Try to enter 5 Enter. Or define temp as std::string.

Upvotes: 2

Related Questions