C++ IsFloat function

If you can't use a Boost library function, you can write your own isFloat function like this.

#include <string>
#include <sstream>

bool isFloat( string myString ) {
    std::istringstream iss(myString);
    float f;
    iss >> noskipws >> f; // noskipws considers leading whitespace invalid
    // Check the entire string was consumed and if either failbit or badbit is set
    return iss.eof() && !iss.fail(); 
}

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...).


You may like Boost's lexical_cast (see http://www.boost.org/doc/libs/1_37_0/libs/conversion/lexical_cast.htm).

bool isFloat(const std::string &someString)
{
  using boost::lexical_cast;
  using boost::bad_lexical_cast; 

  try
  {
    boost::lexical_cast<float>(someString);
  }
  catch (bad_lexical_cast &)
  {
    return false;
  }

  return true;
}

You can use istream to avoid needing Boost, but frankly, Boost is just too good to leave out.