Controlling the state of a stream

I found a program which, given a sequence of data, process the data of a specified type and print a warning for data of different types. The program is the following:

#include <iostream>
using namespace std;

int main(){

int ival;
while (cin >> ival, !cin.eof()) {
if (cin.bad())
throw runtime_error("IO stream corrupted");
if (cin.fail()) {
cerr<< "bad data, try again" << endl;
cin.clear(istream::failbit);
continue;
}
cout << "ival = " << ival << endl;
}

return 0;
}



The problem is that this program doesn’t work, and I absolutely don’t understand where is the error. If I enter the following sequence
1 2 3 w 4 5 6 7
the program loops, giving
ival = 1
ival = 2
ival = 3
bad data, try again
bad data, try again
bad data, try again
...................
...................

What’s wrong?
Thank you
The way the program is written and using the input values you are using, this program will never work.

1. cin.bad will never happen - so the runtime_error exception will not be thrown.

2. You are tring to read an int value. So when the w character is reached, then cin will fail.
BUT - when this happens, we print an error message, clear the fail bit and go round the loop again, tring to read an int value.
We will never get past that w character by tring to read it as an integer, that is why get get in an infinite loop, continually failing and printing the error message.

3. cin.eof() will never happen, because of point 2 above. We never get to the end of the line, because we are stuck trying to get get the w charcater.
So the while loop will never end.
Last edited on
The while condition is quite odd: while (cin >> ival, !cin.eof()) why that comma, did you mean && ?
Last edited on
Based on your comments, I solved the problem by reading the bad data into a string, so the following program does what I want:

#include <iostream>
#include <string>
using namespace std;


int main(){

int ival;
string dump;
while (cin >> ival, !cin.eof()) {
if (cin.bad())
throw runtime_error("IO stream corrupted");
if (cin.fail()) {
cin.clear();
cin >> dump;
cerr<< dump << " is a bad data" << endl;
continue;
}
cout << "ival = " << ival << endl;
}


return 0;
}

I use the comma instead of && in the while because I want the condition be true until the EOF, regardless of bad data.
Thank you for help.
Topic archived. No new replies allowed.