6

What's the best way to convert std::wstring to numeric type, such as int, long, float or double?

1

6 Answers 6

37

C++0x introduces the following functions in <string>:

int                stoi  (const wstring& str, size_t* idx = 0, int base = 10);
long               stol  (const wstring& str, size_t* idx = 0, int base = 10);
unsigned long      stoul (const wstring& str, size_t* idx = 0, int base = 10);
long long          stoll (const wstring& str, size_t* idx = 0, int base = 10);
unsigned long long stoull(const wstring& str, size_t* idx = 0, int base = 10);

float       stof (const wstring& str, size_t* idx = 0);
double      stod (const wstring& str, size_t* idx = 0);
long double stold(const wstring& str, size_t* idx = 0);

idx is an optionally null pointer to the end of the conversion within str (set by the conversion function).

Sign up to request clarification or add additional context in comments.

Comments

18

Either use boost::lexical_cast<>:

#include <boost/lexical_cast.hpp>

std::wstring s1(L"123");
int num = boost::lexical_cast<int>(s1);

std::wstring s2(L"123.5");
double d = boost::lexical_cast<double>(s2);

These will throw a boost::bad_lexical_cast exception if the string can't be converted.

The other option is to use Boost Qi (a sublibrary of Boost.Spirit):

#include <boost/spirit/include/qi.hpp>

std::wstring s1(L"123");
int num = 0;
if (boost::spirit::qi::parse(s1.begin(), s1.end(), num))
    ; // conversion successful

std::wstring s2(L"123.5");
double d = 0;
if (boost::spirit::qi::parse(s1.begin(), s1.end(), d))
    ; // conversion successful

Using Qi is much faster than lexical_cast but will increase your compile times.

1 Comment

And people claim C++ is unecessarily complex!
13

Best?

If you don't want to use anything more than the CRT library, and are happy with getting 0 if the string cannot be converted, then you can save on error handling, complex syntax, including headers by

std::wstring s(L"123.5");
float value = (float) _wtof( s.c_str() );

It all depends what you are doing. This is the KISS way!

3 Comments

Where does _wtof come from?
@david The c run time (CRT) library
I'm not seeing a reference to it either in the C99 Standard or Harbison & Steele. Perhaps wcstod/wcstol/wcstoul would be better.
3

Use wstringstream / stringstream:

#include <sstream>
float toFloat(const std::wstring& strbuf)
{
    std::wstringstream converter;
    float value = 0;

    converter.precision(4);
    converter.fill('0');
    converter.setf( std::ios::fixed, std::ios::floatfield );                              

    converter << strbuf;
    converter >> value;
    return value;
}

Comments

1

just use the stringstream: do not forget to #include <sstream>

wchar_t blank;
wstring sInt(L"123");
wstring sFloat(L"123.456");
wstring sLong(L"1234567890");
int rInt;
float rFloat;
long rLong;

wstringstream convStream;

convStream << sInt<<' '<< sFloat<<' '<<sLong;
convStream >> rInt;
convStream >> rFloat;
convStream >> rLong;
cout << rInt << endl << rFloat << endl << rLong << endl;

Comments

-1

So I was using Embarcadero and that piece of ..... didn´t let me use stoi, so i have to create my own function.

int string_int(wstring lala){
    int numero;
    int completo = 0;
    int exponente = 1;
    int l = 1;
    for (int i = 0; i < lala.size(); i++){
        numero = 0;
        for (int j = 48; j < 57; j++){
            if (lala[i] == j){
                break;
            }
            numero++;
        }
        for (int k = 0; k < lala.size() - l; k++){
            exponente *= 10;
        }
        numero *= exponente;
        completo += numero;
        exponente = 1;
        l++;
    }
    return completo;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.