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.