I\'ve had quite a bit of trouble trying to write a function that checks if a string is a number. For a game I am writing I just need to check if a line from the file I am r
I propose a simple convention:
If conversion to ASCII is > 0 or it starts with 0 then it is a number. It is not perfect but fast.
Something like this:
string token0;
if (atoi(token0.c_str())>0 || isdigit(token0.c_str()[0]) ) { //this is a value
// do what you need to do...
}
After consulting the documentation a bit more, I came up with an answer that supports my needs, but probably won't be as helpful for others. Here it is (without the annoying return true and return false statements :-) )
bool isNumber(string line)
{
return (atoi(line.c_str()));
}
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]+"));
}
With this solution you can check everything from negative to positive numbers and even float numbers. When you change the type of num
to integer you will get an error if the string contains a point.
#include<iostream>
#include<sstream>
using namespace std;
int main()
{
string s;
cin >> s;
stringstream ss;
ss << s;
float num = 0;
ss >> num;
if(ss.good()) {
cerr << "No Valid Number" << endl;
}
else if(num == 0 && s[0] != '0') {
cerr << "No Valid Number" << endl;
}
else {
cout << num<< endl;
}
}
Prove: C++ Program
Brendan this
bool isNumber(string line)
{
return (atoi(line.c_str()));
}
is almost ok.
assuming any string starting with 0 is a number, Just add a check for this case
bool isNumber(const string &line)
{
if (line[0] == '0') return true;
return (atoi(line.c_str()));
}
ofc "123hello" will return true like Tony D noted.
This function takes care of all the possible cases:
bool AppUtilities::checkStringIsNumber(std::string s){
//Eliminate obvious irritants that could spoil the party
//Handle special cases here, e.g. return true for "+", "-", "" if they are acceptable as numbers to you
if (s == "" || s == "." || s == "+" || s == "-" || s == "+." || s == "-.") return false;
//Remove leading / trailing spaces **IF** they are acceptable to you
while (s.size() > 0 && s[0] == ' ') s = s.substr(1, s.size() - 1);
while (s.size() > 0 && s[s.size() - 1] == ' ') s = s.substr(0, s.size() - 1);
//Remove any leading + or - sign
if (s[0] == '+' || s[0] == '-')
s = s.substr(1, s.size() - 1);
//Remove decimal points
long prevLength = s.size();
size_t start_pos = 0;
while((start_pos = s.find(".", start_pos)) != std::string::npos)
s.replace(start_pos, 1, "");
//If the string had more than 2 decimal points, return false.
if (prevLength > s.size() + 1) return false;
//Check that you are left with numbers only!!
//Courtesy selected answer by Charles Salvia above
std::string::const_iterator it = s.begin();
while (it != s.end() && std::isdigit(*it)) ++it;
return !s.empty() && it == s.end();
//Tada....
}