C++ String: How to convert a string into a numeric type?
Q: How to convert a string into a numeric type?
A: There is one thing that you are not allowed to ignore when you convert a string into a numeric type: the conversion might fail because the
string you are converting might not contain a valid representation of a number.
If, for example, you try to convert the string "Hello" to a number, the conversion must fail.
The old C way (deprecated):
Many people use the 'atoi()', 'atof()' and the other functions from this "family". They're easy to use but have a major drawback: they return 0 both on failure and when converting the string "0", thus making a consistent error detection as good as impossible. We give this little sample for the sake of completeness:
Code:
const char* str_int = "777";
const char* str_float = "333.3";
int i = atoi(str_int);
float f = atof(str_float);
A better way:
A bit more complicated, but also more consistent way is to use 'sscanf()' in one of it's flavors:
Code:
const char* str_int = "777";
const char* str_float = "333.3";
int i;
float f;
if(EOF == sscanf(str_int, "%d", &i))
{
//error
}
if(EOF == sscanf(str_float, "%f", &f))
{
//error
}
Since 'sscanf()' takes a 'const char*' parameter, you can directly use a 'CString' with it:
Code:
CString str_int("777");
if(EOF == sscanf(str_int, '%d', &i))
{
//error
}
Be very careful with the format specifier (i.e. "%d" in this example). 'sscanf()' has no way to check whether the format specifier and the type of the passed variable match each other. If they don't you will get unexpected
results. Also note that 'sscanf()' is able to extract more than one numerical value from a string with one call. Have a look in e.g. MSDN for details.
The C++ way
Following sample shows a template function that uses Standard C++ classes to complete the task:
Code:
#include <string>
#include <sstream>
#include <iostream>
template <class T>
bool from_string(T& t,
const std::string& s,
std::ios_base& (*f)(std::ios_base&))
{
std::istringstream iss(s);
return !(iss >> f >> t).fail();
}
int main()
{
int i;
float f;
// the third parameter of from_string() should be
// one of std::hex, std::dec or std::oct</span>
if(from_string<int>(i, std::string("ff"), std::hex))
{
std::cout << i << std::endl;
}
else
{
std::cout << "from_string failed" << std::endl;
}
if(from_string<float>(f, std::string("123.456"), std::dec))
{
std::cout << f << std::endl;
}
else
{
std::cout << "from_string failed" << std::endl;
}
return 0;
}
/* output:
255
123.456
*/
This method is not only elegant but also type safe, because the compiler will pick the proper 'std::istringstream::operator >>()' at compile time, according to the operand type.
<br><br>
Re: C++ String: How to convert a string into a numeric type?
An addition to the FAQ:
The other routine to convert is strtod(). If converting from a string to a floating point type, the usage of 'strtod()' is much safer than 'sscanf()', since
1) the issue of providing the wrong floating point type in the argument list is eliminated, and
2) 'strtod()' will detect if and where a string contains invalid numeric data, and return a pointer to the invalid character in the string (if the string is an invalid numeric string).
If strictly converting from a string to floating point value, 'strtod()' should be recommended instead of 'sscanf()'.
As a matter of fact, any string-to-numeric function that returns the result (as opposed to you giving the address of a variable for 'sscanf()' to manipulate and possibly crash) is preferable. At least with a return value, you can cast it appropriately, or the built-in C or C++ promotion rules will assign the value correctly.
<br><br>
Re: Strings: How to convert a string into a numeric type?
In addition to the above posted comments, an easier & also liable-to-be-standard is boost.org's boost::lexical_cast. Here is an excerpt from the the documentation...
Quote:
Originally Posted by boost.org
lexical_cast is for converting data from one streamable type to another, and it competes more directly with C's atoi() et al. conversion functions as well as with the nonstandard but commonly available itoa() et al. functions.
And also an example shamelessly copied from boost.org...
Code:
int main(int argc, char* argv[])
{
using boost::lexical_cast;
using boost::bad_lexical_cast;
std::vector<short> args;
while(*++argv)
{
try
{
args.push_back(lexical_cast<short>(*argv));
}
catch(bad_lexical_cast&)
{
args.push_back(0);
}
}
...
}
For more info, visit 'boost::lexical_cast'.
<br><br>
Re: C++ String: How to convert a string into a numeric type?
In addition to FAQ:
Please note that using function sccanf() to convert string into f with float type,
Code:
sscanf(str_float, "%f", &f);
The result may not be what you want.
refer to the example of FAQ:
Code:
printf("f is now = %f\n", f);
You will find the out is: f is now = 333.299988
The myth here is sccanf actually convert str_float into double type. if you cast it back to float, there will be some differences, because the way floating point is represented. See this FAQ for more.
Re: C++ String: How to convert a string into a numeric type?
Another one easy solution :
- conversion to string:
Code:
template<class T>
std::string toString(const T& t)
{
std::ostringstream stream;
stream << t;
return stream.str();
}
- conversion from string:
Code:
template<class T>
T fromString(const std::string& s)
{
std::istringstream stream (s);
T t;
stream >> t;
return t;
}