Numeric type conversion to std::string and vice versa
In our real applications we have to convert from strings to integer or to real variables and vice versa (double/float/int variable to std::string).
We can realize these conversions using C style CRT function or we can try C++ approach via STL.
Unfortunately, current C standard libraries do not offer a complete support for any type of conversion. For instance, if we try to put an integer into a C++ string object (std::(w)string) using a well known function itoa() then we get next error:
1 2 3 |
int x1 = 230; std::string s1; itoa(x1, s1, 10); |
// error C2664: ‘itoa’ : cannot convert parameter 2 from ‘std::string’ to ‘char *’
A C style approach in order to avoid this error means using an intermediary buffer:
1 2 3 4 5 |
int x1 = 230; std::string s1; char szBuff[64]={0}; itoa(x1, szBuff, 10); s1 = szBuff; |
Same story if we try to convert a std::string to an int:
1 2 |
std::string s3 = "442"; int x3 = atoi(s3); |
// error C2664: ‘atoi’ : cannot convert parameter 1 from ‘std::string’ to ‘const char *’
In this case we can use c_str() in order to return a constant pointer to char.
1 |
int x3 = atoi(s3.c_str()); |
An elegant way to get rid of such problems is to build two conversion function that use templates and C++ streams.
Base on this idea, I created a Sting2Numeric class that contains two static methods: Type2String() and String2Type().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
class String2Numeric { public: template <class TypeT> static xstring Type2String(TypeT x) { xostringstream o; if (!(o << x)) throw BadConversion("Type2String(TypeT)"); return o.str(); } template <class TypeT> static TypeT String2Type(const xstring& s) { xistringstream i(s); TypeT x; if (!(i >> x)) throw BadConversion("String2Type(TypeT)"); return x; } }; |
where BadConvertion is a std::runtime_error‘s derived class.
1 2 3 4 5 6 |
class BadConversion : public std::runtime_error { public: BadConversion(const std::string& s) : std::runtime_error(s) { } }; |
Because of ANSI and UNICODE project’s compatibility I defined few macros:
1 2 3 4 5 6 7 8 9 |
#ifdef _UNICODE #define xstring std::wstring #define xostringstream std::wostringstream #define xistringstream std::wistringstream #else #define xstring std::string #define xostringstream std::ostringstream #define xistringstream std::istringstream #endif |
Because of this compatibility I strongly recommend using a xstring alias instead of std::wstring or std::string.
When you want to convert an int, float, double, or other numerical type to a xstring in a C++ style you can use the Type2String() function. Vice versa, if you want to convert a xstring to these types you can use String2Type().
In order to avoid possible thrown exception I recommend to you using a try catch block whenever you’re using these functions. I prefer using xstring for string/wstring variables definition, too.
Here is a sample of using this class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
double y1 = 0.2312, y2 = 1.0123; xstring s1 , s2; try { s1 = String2Numeric::Type2String<double>(y1); s2 = String2Numeric::Type2String<int>(x2); #ifdef _UNICODE xstring s3(L"43.52"); #else xstring s3("43.52"); #endif x2 = String2Numeric::String2Type<int>(s3); y2 = String2Numeric::String2Type<double>(s3); } catch (BadConversion &eBC) { std::cout << "An exception has been thrown: " << eBC.what() << std::endl; } |
The String2Numeric class can be extended. For instance, if the conversion throw an error then you can add detailed information in the exception message.
Download String2Numeric (914 downloads) class.