I have a string
which can be either a double
, float
or int
. I would like to convert the string
to the data type by making function calls. I am currently using functions such as stof
and stoi
which throw exceptions when the input is not a float
or int
. Is there another way to convert the strings without having to catch exceptions? Perhaps some function that passes a a pointer to a float
as argument and just returns a boolean
which represents the success of the function of call. I would like to avoid using any try
catch
statements in any of my code.
Use a std::stringstream
and capture the result of operator>>()
.
For example:
#include <string>
#include <iostream>
#include <sstream>
int main(int, char*[])
{
std::stringstream sstr1("12345");
std::stringstream sstr2("foo");
int i1(0);
int i2(0);
//C++98
bool success1 = sstr1 >> i1;
//C++11 (previous is forbidden in c++11)
success1 = sstr1.good();
//C++98
bool success2 = sstr2 >> i2;
//C++11 (previous is forbidden in c++11)
success2 = sstr2.good();
std::cout << "i1=" << i1 << " success=" << success1 << std::endl;
std::cout << "i2=" << i2 << " success=" << success2 << std::endl;
return 0;
}
Prints:
i1=12345 success=1
i2=0 success=0
Note, this is basically what boost::lexical_cast
does, except that boost::lexical_cast
throws a boost::bad_lexical_cast
exception on failure instead of using a return code.
See: http://www.boost.org/doc/libs/1_55_0/doc/html/boost_lexical_cast.html
For std::stringstream::good, see: http://www.cplusplus.com/reference/ios/ios/good/
To avoid exceptions, go back to a time when exceptions didn't exist. These functions were carried over from C but they're still useful today: strtod
and strtol
. (There's also a strtof
but doubles will auto-convert to float anyway). You check for errors by seeing if the decoding reached the end of the string, as indicated by a zero character value.
char * pEnd = NULL;
double d = strtod(str.c_str(), &pEnd);
if (*pEnd) // error was detected
Mark Ransom, you hit the nail on the head. I understand RagHaven because in certain situations exceptions are a nuisance, and converting alphanumeric chains to doubles should be something light and fast, not subject to the exception handling mechanism. I found that a five-alphanumeric string sorting algorithm took more than 3 seconds because exceptions were thrown in the process and somewhere in the software something was complaining.
In my search for conversion functions without launching exceptions I found this (I work with C++ Builder):
double StrToFloatDef(string, double def);
That function tries to return a float, and, if it does not succeed, instead of launching an exception it returns the value that is passed in the 2nd argument (which could for example be put to std::numeric_limits<double>::max())
. Checking if the return value matches 'def' you can control the result without exceptions.
Mark's proposal, std::strtod
, is just as good but much faster, standard and safe. A function like the one RagHaven asks for could look like this:
bool AsDouble(const char* s, double& v) const noexcept
{
char* pEnd = nullptr;
v = std::strtod(s, &pEnd);
return *pEnd == 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With