Silviu-Marius Ardelean's blog

a software engineer's web log

pre vs. post increment operator – benchmark »« Flexible changes for product version properties – Visual C++ binaries

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:
[cpp]
int x1 = 230;
std::string s1;
itoa(x1, s1, 10);
[/cpp]
// 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:
[cpp]
int x1 = 230;
std::string s1;
char szBuff[64]={0};
itoa(x1, szBuff, 10);
s1 = szBuff;
[/cpp]

Same story if we try to convert a std::string to an int:
[cpp]
std::string s3 = “442”;
int x3 = atoi(s3);
[/cpp]
// 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.
[cpp]int x3 = atoi(s3.c_str());[/cpp]

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().
[cpp]
class String2Numeric
{
public:

template
static xstring Type2String(TypeT x)
{
xostringstream o;
if (!(o << x)) throw BadConversion("Type2String(TypeT)"); return o.str(); } template
static TypeT String2Type(const xstring& s)
{
xistringstream i(s);
TypeT x;
if (!(i >> x))
throw BadConversion(“String2Type(TypeT)”);

return x;
}
};
[/cpp]

where BadConvertion is a std::runtime_error‘s derived class.
[cpp]
class BadConversion : public std::runtime_error {
public:
BadConversion(const std::string& s)
: std::runtime_error(s)
{ }
};[/cpp]

Because of ANSI and UNICODE project’s compatibility I defined few macros:
[cpp]
#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
[/cpp]
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:
[cpp]
double y1 = 0.2312, y2 = 1.0123;
xstring s1 , s2;

try
{
s1 = String2Numeric::Type2String(y1);
s2 = String2Numeric::Type2String(x2);

#ifdef _UNICODE
xstring s3(L”43.52″);
#else
xstring s3(“43.52”);
#endif

x2 = String2Numeric::String2Type(s3);
y2 = String2Numeric::String2Type(s3);
}
catch (BadConversion &eBC)
{
std::cout << "An exception has been thrown: " << eBC.what() << std::endl; } [/cpp] 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 (1209 downloads) class.

Silviu Ardelean

Software Engineer

More Posts - Website

Follow Me:
TwitterFacebookPinterest

, , , , ,
15/01/2011 at 6:25 PM
Leave a Reply or trackback

*