Reputation: 9532
I am looking through the istream
class and I don't see a method that cleans completely the buffer and sets the input to be ready for a next "clean" input.
I defined the extraction operator for my class, and in my main program I ask the user for an input, like this:
while (true) {
try {
cout << "Enter input: ";
MyClass c;
cin >> c;
return c;
} catch(const MyException& e) {
cerr << "Error\n";
}
}
If I enter an unexpected incorrect input I am trapped in an infinite loop.
In my overriden extractin method I control when the input is not correct and the exception is thrown, all this is ok. I just want to also clean the istream
object so I prevent the infinite loop.
Upvotes: 0
Views: 436
Reputation: 96835
Firstly, the inserters/extrators for your classes shouldn't throw exceptions. IOStreams were designed not to throw exceptions by default and to remain consistent I would recommend that you not throw custom exceptions from your I/O operators.
As Dieter said, you're better off setting the std::ios_base::failbit
flag in the stream state instead of throwing. You can do this using the setstate()
method. Once you do that, you can check for a valid extraction with an if()
statement. To answer your question, once you determine if the input is invalid, you clear the stream state, and clear the buffer for new input by calling ignore()
discard the rest of the characters:
while (std::cout << "Enter input: ")
{
X x;
if (!(std::cin >> x))
{
std::cout << "Invalid. Try again.\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
continue; // or break if needed
}
// handle good input and break if needed
}
Upvotes: 1