I have been up all night searching for a way to determine if my string value is a valid double and I haven't found a way that will also not reject a number with a point in it...
In my searches I found this
How to determine if a string is a number with C++?
and the answer that Charles Salvia gave was
bool is_number(const std::string& s)
{
std::string::const_iterator it = s.begin();
while (it != s.end() && std::isdigit(*it)) ++it;
return !s.empty() && it == s.end();
}
this works for any number that doesn't have a point in it but a number with a point gets rejected...
Add another check
c == '.'
.You can make the code easier to read by using:
There have been a few answers posted to this, so I figured I would add my own. If you have access to C++17, using charconv may possibly be a more efficient way. I have not benchmarked this, but for most string-conversion applications, charconv is very efficient. This solution also requires a compiler that supports charconv to/from a double. VC++ supports this; I'm not sure which other compilers have implemented this aspect of the standard library.
Upon a successful conversion, std::from_chars returns std::errc(). This is in essence simply wrapping from_chars and discarding the resulting double. Depending on your use case, it might be more advantageous to take the error value and double (assuming the string will be converted to a number later on), but at that point it would make more sense to use use from_chars by itself.
You may be tempted to use
std::stod
like this:but this can be quite inefficient, see e.g. zero-cost exceptions.
So using @Robinson's solution or
strtod
is a better option:You can also count how many points your string contains. If this number is less or equal than 1 and if all other characters are numbers, your string is a valid double.
You can also use a regex if you know how to deal with that...
Making sure there is at most one dot in the number.
You could use
std::istringstream()
. It tells you if there is any non-numerics following the digits by not setting theeof()
flag.Output:
Templated Version: For testing specific types
Output: