tags:

views:

116

answers:

2

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?

+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
+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
Thanks for this! What would be the proper way to catch this exception? Or just a generic exception handler?
Chris
@Chris Updated with exception handing example.
Tim Sylvester
Boost defines `class bad_lexical_cast : public std::bad_cast`, just catch it as any other exception.
Aurélien Vallée
Question, does this wistringstream work for floats as well? Trying to avoid including boost in my project :)
Chris
@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
Wonderful. And I do not need to close these streams at all?
Chris
@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
@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