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

后端 未结 30 1915
遇见更好的自我
遇见更好的自我 2020-11-22 08:46

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

相关标签:
30条回答
  • 2020-11-22 09:03

    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

    0 讨论(0)
  • 2020-11-22 09:04

    I've found the following code to be the most robust (c++11). It catches both integers and floats.

    #include <regex>
    bool isNumber( std::string token )
    {
        return std::regex_match( token, std::regex( ( "((\\+|-)?[[:digit:]]+)(\\.(([[:digit:]]+)?))?" ) ) );
    }
    
    0 讨论(0)
  • 2020-11-22 09:05

    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 }
    
    0 讨论(0)
  • 2020-11-22 09:05

    C/C++ style for unsigned integers, using range based for C++11:

    int isdigits(const std::string & s)
    {
        for (char c : s) if (!isdigit(c)) return (0);
        return (1);
    }
    
    0 讨论(0)
  • 2020-11-22 09:06

    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
    }
    
    0 讨论(0)
  • 2020-11-22 09:06

    Few months ago, I implemented a way to determine if any string is integer, hexadecimal or double.

    enum{
            STRING_IS_INVALID_NUMBER=0,
            STRING_IS_HEXA,
            STRING_IS_INT,
            STRING_IS_DOUBLE
    };
    
    bool isDigit(char c){
        return (('0' <= c) && (c<='9'));
    }
    
    bool isHexaDigit(char c){
        return ((('0' <= c) && (c<='9')) || ((tolower(c)<='a')&&(tolower(c)<='f')));
    }
    
    
    char *ADVANCE_DIGITS(char *aux_p){
    
        while(CString::isDigit(*aux_p)) aux_p++;
        return aux_p;
    }
    
    char *ADVANCE_HEXADIGITS(char *aux_p){
    
        while(CString::isHexaDigit(*aux_p)) aux_p++;
        return aux_p;
    }
    
    
    int isNumber(const string & test_str_number){
        bool isHexa=false;
        char *str = (char *)test_str_number.c_str();
    
        switch(*str){
        case '-': str++; // is negative number ...
                   break;
        case '0': 
                  if(tolower(*str+1)=='x')  {
                      isHexa = true;
                      str+=2;
                  }
                  break;
        default:
                break;
        };
    
        char *start_str = str; // saves start position...
        if(isHexa) { // candidate to hexa ...
            str = ADVANCE_HEXADIGITS(str);
            if(str == start_str)
                return STRING_IS_INVALID_NUMBER;
    
            if(*str == ' ' || *str == 0) 
                return STRING_IS_HEXA;
    
        }else{ // test if integer or float
            str = ADVANCE_DIGITS(str);
            if(*str=='.') { // is candidate to double
                str++;
                str = ADVANCE_DIGITS(str);
                if(*str == ' ' || *str == 0)
                    return STRING_IS_DOUBLE;
    
                return STRING_IS_INVALID_NUMBER;
            }
    
            if(*str == ' ' || *str == 0)
                return STRING_IS_INT;
    
        }
    
        return STRING_IS_INVALID_NUMBER;
    
    
    }
    

    Then in your program you can easily convert the number in function its type if you do the following,

    string val; // the string to check if number...
    
    switch(isNumber(val)){
       case STRING_IS_HEXA: 
       // use strtol(val.c_str(), NULL, 16); to convert it into conventional hexadecimal
       break;
       case STRING_IS_INT: 
       // use (int)strtol(val.c_str(), NULL, 10); to convert it into conventional integer
       break;
       case STRING_IS_DOUBLE:
       // use atof(val.c_str()); to convert it into conventional float/double
       break;
    }
    

    You can realise that the function will return a 0 if the number wasn't detected. The 0 it can be treated as false (like boolean).

    0 讨论(0)
提交回复
热议问题