C++ IsFloat function

前端 未结 18 1278
不思量自难忘°
不思量自难忘° 2020-12-09 15:58

Does anybody know of a convenient means of determining if a string value \"qualifies\" as a floating-point number?

bool IsFloat( string MyString )
{
   ... e         


        
相关标签:
18条回答
  • 2020-12-09 16:51

    You can use the methods described in How can I convert string to double in C++?, and instead of throwing a conversion_error, return false (indicating the string does not represent a float), and true otherwise.

    0 讨论(0)
  • 2020-12-09 16:52

    Inspired by this answer I modified the function to check if a string is a floating point number. It won't require boost & doesn't relies on stringstreams failbit - it's just plain parsing.

    static bool isFloatNumber(const std::string& string){
        std::string::const_iterator it = string.begin();
        bool decimalPoint = false;
        int minSize = 0;
        if(string.size()>0 && (string[0] == '-' || string[0] == '+')){
          it++;
          minSize++;
        }
        while(it != string.end()){
          if(*it == '.'){
            if(!decimalPoint) decimalPoint = true;
            else break;
          }else if(!std::isdigit(*it) && ((*it!='f') || it+1 != string.end() || !decimalPoint)){
            break;
          }
          ++it;
        }
        return string.size()>minSize && it == string.end();
      }
    

    I.e.

    1
    2.
    3.10000
    4.2f
    -5.3f
    +6.2f
    

    is recognized by this function correctly as float.

    1.0.0
    2f
    2.0f1
    

    Are examples for not-valid floats. If you don't want to recognize floating point numbers in the format X.XXf, just remove the condition:

    && ((*it!='f') || it+1 != string.end() || !decimalPoint)
    

    from line 9. And if you don't want to recognize numbers without '.' as float (i.e. not '1', only '1.', '1.0', '1.0f'...) then you can change the last line to:

    return string.size()>minSize && it == string.end() && decimalPoint;
    

    However: There are plenty good reasons to use either boost's lexical_cast or the solution using stringstreams rather than this 'ugly function'. But It gives me more control over what kind of formats exactly I want to recognize as floating point numbers (i.e. maximum digits after decimal point...).

    0 讨论(0)
  • 2020-12-09 16:52

    What you could do is use an istringstream and return true/false based on the result of the stream operation. Something like this (warning - I haven't even compiled the code, it's a guideline only):

    float potential_float_value;
    std::istringstream could_be_a_float(MyString)
    could_be_a_float >> potential_float_value;
    
    return could_be_a_float.fail() ? false : true;
    
    0 讨论(0)
  • With C++17:

    bool isNumeric(std::string_view s)
    {
        double val;
        auto [p, ec] = std::from_chars(s.data(), s.data() + s.size(), val);
        return ec == std::errc() && p == s.data() + s.size();
    }
    

    Both checks on return are necessary. The first checks that there are no overflow or other errors. The second checks that the entire string was read.

    0 讨论(0)
  • 2020-12-09 16:58

    [EDIT: Fixed to forbid initial whitespace and trailing nonsense.]

    #include <sstream>
    
    bool isFloat(string s) {
        istringstream iss(s);
        float dummy;
        iss >> noskipws >> dummy;
        return iss && iss.eof();     // Result converted to bool
    }
    

    You could easily turn this into a function templated on a type T instead of float. This is essentially what Boost's lexical_cast does.

    0 讨论(0)
  • 2020-12-09 17:00

    This is a common question on SO. Look at this question for suggestions (that question discusses string->int, but the approaches are the same).

    Note: to know if the string can be converted, you basically have to do the conversion to check for things like over/underflow.

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