The most efficient way would be just to iterate over the string until you find a non-digit character. If there are any non-digit characters, you can consider the string not a number.
bool is_number(const std::string& s)
{
std::string::const_iterator it = s.begin();
while (it != s.end() && std::isdigit(*it)) ++it;
return !s.empty() && it == s.end();
}
Or if you want to do it the C++11 way:
bool is_number(const std::string& s)
{
return !s.empty() && std::find_if(s.begin(),
s.end(), [](unsigned char c) { return !std::isdigit(c); }) == s.end();
}
As pointed out in the comments below, this only works for positive integers. If you need to detect negative integers or fractions, you should go with a more robust library-based solution. Although, adding support for negative integers is pretty trivial.
Why reinvent the wheel? The C standard library (available in C++ as well) has a function that does exactly this:
char* p;
long converted = strtol(s, &p, 10);
if (*p) {
// conversion failed because the input wasn't a number
}
else {
// use converted
}
If you want to handle fractions or scientific notation, go with strtod
instead (you'll get a double
result).
If you want to allow hexadecimal and octal constants in C/C++ style ("0xABC"
), then make the last parameter 0
instead.
Your function then can be written as
bool isParam(string line)
{
char* p;
strtol(line.c_str(), &p, 10);
return *p == 0;
}
With C++11 compiler, for non-negative integers I would use something like this (note the ::
instead of std::
):
bool is_number(const std::string &s) {
return !s.empty() && std::all_of(s.begin(), s.end(), ::isdigit);
}
http://ideone.com/OjVJWh
You can do it the C++ way with boost::lexical_cast. If you really insist on not using boost you can just examine what it does and do that. It's pretty simple.
try
{
double x = boost::lexical_cast<double>(str); // double could be anything with >> operator.
}
catch(...) { oops, not a number }
I'd suggest a regex approach. A full regex-match (for example, using boost::regex) with
-?[0-9]+([\.][0-9]+)?
would show whether the string is a number or not. This includes positive and negative numbers, integer as well as decimal.
Other variations:
[0-9]+([\.][0-9]+)?
(only positive)
-?[0-9]+
(only integer)
[0-9]+
(only positive integer)
I just wanted to throw in this idea that uses iteration but some other code does that iteration:
#include <string.h>
bool is_number(const std::string& s)
{
return( strspn( s.c_str(), "-.0123456789" ) == s.size() );
}
It's not robust like it should be when checking for a decimal point or minus sign since it allows there to be more than one of each and in any location. The good thing is that it's a single line of code and doesn't require a third-party library.
Take out the '.' and '-' if positive integers are all that are allowed.
Here's another way of doing it using the <regex>
library:
bool is_integer(const std::string & s){
return std::regex_match(s, std::regex("[(-|+)|][0-9]+"));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With