I have a function which returns the inner text of an xml element. It returns it, however, as a const wchar_t*
. I wish to return this value as an integer (And a float in some other cases). What is the best method for doing so?
views:
116answers:
2
+2
A:
1) manual parsing (using sprintf
& atof
/atoi
for instance)
2) using boost::lexical_cast
(see http://www.boost.org/doc/libs/1%5F40%5F0/libs/conversion/lexical%5Fcast.htm)
3) using string streams (http://www.cplusplus.com/reference/iostream/ostringstream/)
Aurélien Vallée
2009-11-15 00:10:26
+7
A:
The C++ way would be:
wchar_t* foo = L"123";
std::wistringstream s(foo);
int i = 0;
s >> i;
With Boost, you could do:
try {
int i2 = boost::lexical_cast<int>(foo);
} catch (boost::bad_lexical_cast const&) {
...
}
Depending on which CRT implementation you're using you may have "wide" atoi
/strtol
functions:
int i = _wtoi(foo);
long l = _wcstol(foo, NULL, 10);
Tim Sylvester
2009-11-15 00:11:12
Thanks for this! What would be the proper way to catch this exception? Or just a generic exception handler?
Chris
2009-11-15 00:13:24
@Chris Updated with exception handing example.
Tim Sylvester
2009-11-15 00:15:14
Boost defines `class bad_lexical_cast : public std::bad_cast`, just catch it as any other exception.
Aurélien Vallée
2009-11-15 00:15:23
Question, does this wistringstream work for floats as well? Trying to avoid including boost in my project :)
Chris
2009-11-15 01:00:50
@Chris Yes, both the C++ and Boost solutions work fine for `float`, `double`, `long long`, etc.. (Of course, you need to change the `<int>` to `<float>` or whatever in the Boost example, or wrap it in a templated function call to infer the correct type). Both solutions can also be extended to work for your own custom types, as well by defining an overload of `operator<<` and a template specialization, respectively.
Tim Sylvester
2009-11-15 01:08:23
Wonderful. And I do not need to close these streams at all?
Chris
2009-11-15 01:27:39
@Chris The `std::wistringstream` object makes a copy of the input string and cleans itself up when it goes out of scope. There's no need to call `close` or anything, though you may want to check the state of the stream after the extraction to see whether it was successful. If something goes wrong, e.g. parsing "NaN", then `s.fail()` will be true. If the entire input is processed, `s.eof()` will be true, as opposed to parsing, e.g., "123x" where `eof()` and `fail()` will both be false.
Tim Sylvester
2009-11-15 02:48:46
@Chris You can shortcut this by doing `if((s >> i).fail())` (or equivalently `if(!(s >> i))`) or `if(s >> i)` to detect whether any value was set into `i`.
Tim Sylvester
2009-11-15 02:54:48