How to check if input is numeric in C++
I want to create a program that takes in integer input from the user and the开发者_JAVA技巧n terminates when the user doesn't enter anything at all (ie, just presses enter). However, I'm having trouble validating the input (making sure that the user is inputting integers, not strings. atoi() won't work, since the integer inputs can be more than one digit.
What is the best way of validating this input? I tried something like the following, but I'm not sure how to complete it:
char input
while( cin>>input != '\n')
{
//some way to check if input is a valid number
while(!inputIsNumeric)
{
cin>>input;
}
}
When cin
gets input it can't use, it sets failbit
:
int n;
cin >> n;
if(!cin) // or if(cin.fail())
{
// user didn't input a number
cin.clear(); // reset failbit
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //skip bad input
// next, request user reinput
}
When cin
's failbit
is set, use cin.clear()
to reset the state of the stream, then cin.ignore()
to expunge the remaining input, and then request that the user re-input. The stream will misbehave so long as the failure state is set and the stream contains bad input.
Check out std::isdigit()
function.
The problem with the usage of
cin>>number_variable;
is that when you input 123abc value, it will pass and your variable will contain 123.
You can use regex, something like this
double inputNumber()
{
string str;
regex regex_pattern("-?[0-9]+.?[0-9]+");
do
{
cout << "Input a positive number: ";
cin >> str;
}while(!regex_match(str,regex_pattern));
return stod(str);
}
Or you can change the regex_pattern to validate anything that you would like.
I find myself using boost::lexical_cast
for this sort of thing all the time these days.
Example:
std::string input;
std::getline(std::cin,input);
int input_value;
try {
input_value=boost::lexical_cast<int>(input));
} catch(boost::bad_lexical_cast &) {
// Deal with bad input here
}
The pattern works just as well for your own classes too, provided they meet some simple requirements (streamability in the necessary direction, and default and copy constructors).
Why not just using scanf("%i") and check its return?
I guess ctype.h is the header file that you need to look at. it has numerous functions for handling digits as well as characters. isdigit or iswdigit is something that will help you in this case.
Here is a reference: http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devwin32/isdigit_xml.html
If you already have the string, you can use this function:
bool isNumber( const string& s )
{
bool hitDecimal=0;
for( char c : s )
{
if( c=='.' && !hitDecimal ) // 2 '.' in string mean invalid
hitDecimal=1; // first hit here, we forgive and skip
else if( !isdigit( c ) )
return 0 ; // not ., not
}
return 1 ;
}
Something that can be done is read text input and then try to convert that to a number:
try
{
std::string str;
std::getline(std::cin, str)
age = std::stoi(str)
}
catch(...)
{
// ...
}
Then you can handle the errors by catching the exceptions.
https://en.cppreference.com/w/cpp/string/basic_string/stol
精彩评论