Reputation: 71
I'm currently working on a fairly basic piece of code here. I'm attempting to check the user's input so that if it is anything other than a number as requested, an error message will pop up and a new input will be requested. I'm using a while loop that should be reset when the continue statement is hit, however it always ends up falling into an infinite loop repeating the error message if an there is an invalid input. Any help would be appreciated, thanks!
while (tester != 1){
cout << "Enter your answer: ";
cin >> userInput;
if (cin.fail()){ //check if user input is valid
cout << "Error: that is not a valid integer.\n";
continue; //continue skips to top of loop if user input is invalid, allowing another attempt
} else{
tester = 1; //Tester variable allows loop to end when good value input
}
}
Upvotes: 1
Views: 702
Reputation: 881113
You need to clear your input buffer after the failure.
If cin >> something
fails, it will not consume the "faulty" data from the input stream and, the next time you go back to get more, it will read the same faulty data.
It will continue to do this until the cows come home, as my grandma used to say - don't ask me what that meant, I'm pretty certain she didn't spend a lot of her time lucid :-)
You can consume to end of line with something like:
#include <limits>
:
std::cin.clear();
std::cin.ignore(
std::numeric_limits<std::streamsize>::max(),
'\n');
Here's a complete program showing it in action:
#include <iostream>
#include <limits>
int main() {
int userInput, tester = 0;
while (tester != 1){
std::cout << "Enter your answer: ";
std::cin >> userInput;
if (std::cin.fail()) {
std::cout << "Not a valid integer.\n";
std::cin.clear();
std::cin.ignore(
std::numeric_limits<std::streamsize>::max(),
'\n');
continue;
} else {
tester = 1;
}
}
return 0;
}
Note especially the use of
std::numeric_limits<std::streamsize>::max()
as the length, this means there is no limit enforced. A lot of people will use INT_MAX
in this situation but this is not the same thing.
It's unlikely to matter in practice since INT_MAX
is a very large number and you'll probably meet end of line before you ignore that many characters but it's better to use the correct value to guarantee behaviour.
Upvotes: 3
Reputation: 747
You need to clear the failed flag and usually also need to skip the next new line character.
This is how normally its done:
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Upvotes: 1