I wrote the following code to check whether the input(answer3) is a number or string, if it is not a number it should return \"Enter Numbers Only\" but it returns the same e
You can use regex
to do this:
#include <regex>
bool isNumber(std::string x){
std::regex e ("^-?\\d+");
if (std::regex_match (x,e)) return true;
else return false;}
If you want to make isNumber()
a generic function which can take any type of input:
#include <regex>
#include <sstream>
template<typename T>
bool isNumber(T x){
std::string s;
std::regex e ("^-?\\d+");
std::stringstream ss;
ss << x;
ss >>s;
if (std::regex_match (s,e)) return true;
else return false;}
The above isNumber()
function checks for integer only, double or float value with precision (which contains dot .
) will not return true.
If you want precision too, then change the regex
line to:
std::regex e ("^-?\\d*\\.?\\d+");
If you want a more efficient solution, see this one.
This is a somewhat old question, but I figured I'd add my own solution that I'm using in my code.
Another way to check if a string is a number is the std::stod
function, which has been mentioned, but I use it a bit differently. In my use case, I use a try-catch block to check if the input is a string or number, like so with your code:
...
try {
double n = stod(answer3);
//This will only be reached if the number was converted properly.
cout << "Correct" << endl;
} catch (invalid_argument &ex) {
cout << "Enter Numbers Only" << endl;
}
...
The primary problem with this solution is that strings that begin with numbers (but aren't all numbers) will be converted to numbers. This can be easily fixed by using std::to_string
on the returned number and comparing it to the original string.
If you're using C++98, you can use stringstreams
(#include <sstream>
):
std::string s = "1234798797";
std::istringstream iss(s);
int num = 0;
if (!(iss >> num).fail()) {
std::cout << num << std::endl;
}
else {
std::cerr << "There was a problem converting the string to an integer!" << std::endl;
}
If boost is available to you, you can use lexical_cast (#include <boost/lexical_cast.hpp>
):
std::string s = "1234798797";
int num = boost::lexical_cast<int>(si);//num is 1234798797
std::cout << num << std::endl;
If C++11 is available to you, you can use the builtin std::stoi
function from <string>
:
std::string s = "1234798797";
int mynum = std::stoi(s);
std::cout << mynum << std::endl;
OUTPUTS:
1234798797
The input to isdigit
is an integer value. However, it will return true (non-zero) only if the value corresponds to '0'-'9'. If you convert them to integer values, they are 48-57. For all other values, isdigit
will return false (zero).
You can check whether you got an integer by changing checking logic:
if ( cin.fail() )
{
cout<<"Correct"<<endl;
}
else
{
cout<<"Enter Numbers Only"<<endl;
}
Another answer using strtod:
bool isNumber(const std::string& s){
if(s.empty() || std::isspace(s[0]) || std::isalpha(s[0])) return false ;
char * p ;
strtod(s.c_str(), &p) ;
return (*p == 0) ;
}
To be able to handle any type of parameter use template:
#include <sstream>
template<typename T>
bool isNumber(T x){
std::string s;
std::stringstream ss;
ss << x;
ss >>s;
if(s.empty() || std::isspace(s[0]) || std::isalpha(s[0])) return false ;
char * p ;
strtod(s.c_str(), &p) ;
return (*p == 0) ;
}
Note:
NAN
and INF
will make it return false (to be exact, any character except valid exponent will make it return false). If you want to allow nan
and inf
, delete the || std::isalpha(s[0])
part.The interest phenomenon are the isdigit
requires char
to be cast to unsigned char
. (Also see here).