Reputation: 97
I have looked in several places on the Internet but cannot find what I am looking for. Basically I am trying to understand data validation and filter out all user input except either the number 1 or 2. I have found information for validating ints. Found stuff on filtering out chars and strings. But when I try to put them together it doesn't work. Basically if the user enters something that is not 1 or 2, it does not end a loop asking for correct input.
I have included more details in the comments in the code below.
Any help is appreciated!
#include <iostream>
#include <string>
int main()
{
std::cout << "Please enter 1 or 2. No other numbers or characters."
<< std::endl;
std::string numberString;
//Used a string so if the user enters a char it gets converted to an
//integer value of 0.
getline(std::cin, numberString);
int numberInteger = atoi(numberString.c_str());
//If the user enters the wrong number, char, or string,
//the program goes to this area of code.
//But if a subsequent correct entry is made, the loop does not end.
if (numberInteger < 1 || numberInteger > 2)
{
do
{
//Tried using these two lines of code to clear the input buffer,
//but it doesn't seem to work either:
//std::cin.clear();
//std::cin.ignore(std::numeric_limits <std::streamsize>::max(), '\n');
std::cout << "Invalid input. Please enter 1 or 2. No other numbers or characters."
<< std::endl;
getline(std::cin, numberString);
int numberInteger = atoi(numberString.c_str());
} while (numberInteger < 1 || numberInteger > 2);
}
else
{
std::cout << "You entered either 1 or 2. Great job! "
<< std::endl;
}
return 0;
}
Upvotes: 1
Views: 620
Reputation: 13134
#include <cctype>
#include <limits>
#include <iostream>
std::istream& eat_whitespace(std::istream& is)
{
int ch;
while ((ch = is.peek()) != EOF && ch != '\n' &&
std::isspace(static_cast<char unsigned>(ch))) // 0)
is.get(); // As long as the next character
// is a space, get and discard it.
return is;
}
int main()
{
int choice;
while (std::cout << "Please enter 1 or 2. No other numbers or characters: ",
!(std::cin >> std::skipws >> choice >> eat_whitespace) || // 1)
std::cin.peek() != '\n' || // 2)
choice < 1 || 2 < choice) { // 3)
std::cerr << "I said 1 or 2 ... nothing else ... grrr!\n\n";
std::cin.clear(); // 4)
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 5)
}
std::cout << "Input was " << choice << '\n';
}
0) Don't feed isspace()
negative values.
1) Extraction of an int
failed. Allow whitespace before and after the int
.
2) If the next character in the stream is not a newline character, there is garbage left eat_whitespace()
didn't swallow --> complain.
3) choice
not in range.
4) clear flags to make sure input functions will work again.
5) ignore up to maximum streamsize
characters untill the next newline.
Upvotes: 1