When running the following code and enter a number, it works fine.
But when entering a letter, the program enters an infinite loop, displaying “Enter a number (0 to exit): cin failed.”
My intent was to handle the cin fail case and prompt the user again.
int number;
do{
cout << "Enter a number (0 to exit): ";
cin >> number;
if(cin.fail()){
cout << "cin failed." << endl;
cin.clear();
}else{
cout << "cin succeeded, " << number << " entered." << endl;
}
}while(number != 0);
You need to clear the line from cin, using cin.ignore, in addition to clearing the stream state (which is what cin.clear does).
I have several utility functions to make this easier (you’ll be interested in clearline in particular, which clears the stream state and the current line) and almost an exact example of what you want.
Your code, more or less, using my clearline:
There is still a potential issue here (fixed in my clinput_loop.cpp with blankline), with leaving input in the buffer that will screw up later IO (see “42 abc” in the sample session). Extracting the above code into a separate and self-contained function is left as an exercise for the reader, but here’s a skeleton:
Example use:
clearline function extracted for posterity, in case above links ever break (and slightly changed to make self-contained):
The template stuff is a bit confusing if you’re not used to it, but it’s not hard:
std::basic_istream<char, std::char_traits<char> >std::basic_istream<wchar_t, std::char_traits<wchar_t> >'\n'to becomeL'\n'as appropriateclearline(stream)orstream >> clearline, compare to other manipulators like std::endl, std::ws, or std::boolalpha