How to determine if a string is a number with C++?

2018-12-31 18:04发布

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 reading is a number or not (I will know if it is a parameter this way). I wrote the below function which I believe was working smoothly (or I accidentally edited to stop it or I'm schizophrenic or Windows is schizophrenic):

bool isParam (string line)
{
    if (isdigit(atoi(line.c_str())))
        return true;

    return false;
}

28条回答
与风俱净
2楼-- · 2018-12-31 18:25

I think this regular expression should handle almost all cases

"^(\\-|\\+)?[0-9]*(\\.[0-9]+)?"

so you can try the following function that can work with both (Unicode and ANSI)

bool IsNumber(CString Cs){
Cs.Trim();

#ifdef _UNICODE
std::wstring sr = (LPCWSTR)Cs.GetBuffer(Cs.GetLength());
return std::regex_match(sr, std::wregex(_T("^(\\-|\\+)?[0-9]*(\\.[0-9]+)?")));

#else
    std::string s = (LPCSTR)Cs.GetBuffer();
return std::regex_match(s, std::regex("^(\\-|\\+)?[0-9]*(\\.[0-9]+)?"));
#endif
}
查看更多
闭嘴吧你
3楼-- · 2018-12-31 18:29

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...
}
查看更多
千与千寻千般痛.
4楼-- · 2018-12-31 18:29

Could you simply use sscanf's return code to determine if it's an int?

bool is_number(const std::string& s)
{
    int value;
    int result = sscanf(valueStr.c_str(), "%d", &value);
    return (result != EOF && readResult != 0);
}
查看更多
与风俱净
5楼-- · 2018-12-31 18:31

As it was revealed to me in an answer to my related question, I feel you should use boost::conversion::try_lexical_convert

查看更多
查无此人
6楼-- · 2018-12-31 18:31

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())); 
}
查看更多
步步皆殇っ
7楼-- · 2018-12-31 18:32

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(), [](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.

查看更多
登录 后发表回答