Another approach is to use the strtod(const char* nptr, char** endptr) function. You pass the string containing the number, and the address to a char* which will be set by the function to the first non-numeric character. FWIW, strtod() [double] and strtof() [float] will also accept scientific notation, such as 1.254e25. This is the technique I usually use, although I also will utilize an algorithm that walks through the string to check each character in some specific (rare) circumstances where I need to validate a particular numeric format.
rubberman
Posting Maven
2,571 posts since Mar 2010
Reputation Points: 365
Solved Threads: 305
Skill Endorsements: 51
You could use boost::lexical_cast to try and convert the string to a number and catch the boost::bad_lexical_cast exception that's thrown if the conversion can't be done. This feels a bit weird though, as I generally try not to use exceptions for flow control. I guess you should wrap it in a function that catches the exception and returns false. You could also do additional validation in this function too, like checking it's actually decimal and not octal or hexadecimal or something.
ravenous
Practically a Master Poster
681 posts since Jul 2005
Reputation Points: 286
Solved Threads: 111
Skill Endorsements: 8
Another approach is to use the strtod(const char* nptr, char** endptr) function.
You could use boost::lexical_cast to try and convert the string to a number
I'm curious how these two approches actually test for valid values. Won't they both simply convert whatever it can to binary and stop when an invalid character is seen? The OP did say
need to check whether all digit is numeric.
WaltP
Posting Sage w/ dash of thyme
11,404 posts since May 2006
Reputation Points: 3,421
Solved Threads: 1,055
Skill Endorsements: 36
I'm curious how these two approches actually test for valid values.
At least for strtod(), a combination of the return value and end pointer as the second argument can be used to validate the string. If conversion stopped before the end of the string, then it's not valid.
I'm not sure about the latest implementation of boost::lexical_cast, but originally it was based on a stringstream and you could test for error or eof status.
Of course, there might be a remaining issue if the OP wants to validate an arbitrary length value, because strtod() and boost::lexical cast are limited to the size of a double for the implementation.
deceptikon
Challenge Accepted
3,427 posts since Jan 2012
Reputation Points: 822
Solved Threads: 473
Skill Endorsements: 56
WaltP
Posting Sage w/ dash of thyme
11,404 posts since May 2006
Reputation Points: 3,421
Solved Threads: 1,055
Skill Endorsements: 36
Won't they both simply convert whatever it can to binary and stop when an invalid character is seen?
boost::lexical_cast will throw boost::bad_lexical_cast if the string can't be fully converted to the kind of value that you specify. For example, the following prints "That's not a valid number!":
#include <iostream>
#include <string>
#include <boost/lexical_cast.hpp>
int main()
{
std::string str( "-1.23x2e2" );
try {
std::cout << boost::lexical_cast< double >( str ) << std::endl;
}
catch ( const boost::bad_lexical_cast& ) {
std::cout << "That's not a valid number!" << std::endl;
}
return 0;
}
However, if you remove the x from the middle of str you will, correctly, see -123.2.
ravenous
Practically a Master Poster
681 posts since Jul 2005
Reputation Points: 286
Solved Threads: 111
Skill Endorsements: 8