I need to know how to make my cin statement not appear to \'remove\' itself if you input the wrong type. The code is here:
int mathOperator()
{
using names
I agree that a char is just as handy, since you can always cast to int, to answer your question as to why this is happening, when a cin input is exected as an int but a char is entered, the input is kept in the input stream for the duration of the loop, which is why it seems to "disappear."
For more information: see the post from Narue at http://www.daniweb.com/forums/thread11505.html
don't read int
, read char
so cin will pass any invalid character
After reading in a bad value, cin is in a "failed" state. You have to reset this.
You must both clear the error flag and empty the buffer. thus:
cin.clear();
cin.ignore(std::numeric_limits<streamsize>::max(), '\n');
The second call "flushes" the input buffer of any data that might be there, to get you ready for the next "cin" call.
If you find yourself writing these 2 lines "all over your code" you could write a simple inline function to replace it.
inline void reset( std::istream & is )
{
is.clear();
is.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
}
Although I have made this function take any istream, most of the time it would only be used for cin
where a user is entering and enters something invalid. If it's an invalid file or stringstream input, there is no way to fix it and you would do best to just throw an exception.
You must check that input succeeded and handle when it doesn't:
int mathOperator() {
using namespace std;
int Input;
do {
cout << "Choose: ";
el();
cout << "1) Addition";
el();
cout << "2) Subtraction";
el();
cout << "3) Multiplication";
el();
cout << "4) Division";
el();
el();
while (!(cin >> Input)) { // failed to extract
if (cin.eof()) { // testing eof() *after* failure detected
throw std::runtime_error("unexpected EOF on stdin");
}
cin.clear(); // clear stream state
cin.ignore(INT_MAX, '\n'); // ignore rest of line
cout << "Input error. Try again!\n";
}
} while (Input != 1 && Input != 2 && Input!=3 && Input!=4);
return Input;
}
If you don't check that extraction succeeded, then cin is left in a failed state (cin.fail()). Once in a failed state, later extractions will immediately return instead of trying to read from the stream, effectively making them no-ops – leading to your infinite loop.
Unless you're quite certain about the input being in the proper format, you rarely want to use operator>>
directly from the input stream.
It's usually easier to read a line with std::getline
, put that into a std::istringstream
, and read from there. If that fails, you print/log an error message, throw away the remainder of the line and (possibly) go on to the next line.
char Input;
do
{
// same code
}
while (Input != '1' && Input != '2' && Input != '3' && Input!='4');
return Input;
[EDIT]
If you want convert char to int you can use this piece of code
int i = (Input - 48);