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:
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:
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:
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.
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().
where BadConvertion is a std::runtime_error‘s derived class.
class BadConversion : public std::runtime_error {
public:
BadConversion(const std::string& s)
: std::runtime_error(s) { }
};
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;
}
};
Because of ANSI and UNICODE project’s compatibility I defined few macros:
#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:
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;
}
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 (4295 downloads ) class.