Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. ATL / WTL / STL
  4. Best way to convert from std::wstring to std::string?

Best way to convert from std::wstring to std::string?

Scheduled Pinned Locked Moved ATL / WTL / STL
phpcomhelpquestionlearning
6 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    David ONeil
    wrote on last edited by
    #1

    It has been awhile since I've looked this deeply into things. Is the following a good way to convert from a wstring to a string?

    std::string dwl::convertWstrToStdString(const std::wstring & wStr) {
    const std::locale & loc = std::wcout.getloc();
    std::string str;
    str.resize(wStr.size()); //If there are cases where the string takes more characters
    //than the wstring, we've got a problem.
    std::string::iterator it = str.begin();
    for (std::wstring::const_iterator wit = wStr.begin(); wit != wStr.end(); ++wit) {
    *it = std::use_facet<std::ctype<wchar_t> >(loc).narrow(*wit);
    ++it;
    }
    return str;
    }

    Or is the 'str.resize' note (or something else) going to bite in the future? Will the str iterator correctly increment if the character it points to will be a Multi Byte character? Should I just use WideCharToMultiByte() and massage it into a std::string? Thanks, David

    My website :: The astronomy of our ancestors: Book :: Videos

    D _ 2 Replies Last reply
    0
    • D David ONeil

      It has been awhile since I've looked this deeply into things. Is the following a good way to convert from a wstring to a string?

      std::string dwl::convertWstrToStdString(const std::wstring & wStr) {
      const std::locale & loc = std::wcout.getloc();
      std::string str;
      str.resize(wStr.size()); //If there are cases where the string takes more characters
      //than the wstring, we've got a problem.
      std::string::iterator it = str.begin();
      for (std::wstring::const_iterator wit = wStr.begin(); wit != wStr.end(); ++wit) {
      *it = std::use_facet<std::ctype<wchar_t> >(loc).narrow(*wit);
      ++it;
      }
      return str;
      }

      Or is the 'str.resize' note (or something else) going to bite in the future? Will the str iterator correctly increment if the character it points to will be a Multi Byte character? Should I just use WideCharToMultiByte() and massage it into a std::string? Thanks, David

      My website :: The astronomy of our ancestors: Book :: Videos

      D Offline
      D Offline
      David ONeil
      wrote on last edited by
      #2

      After more searching, I went with the following. CStrWrap is just a thin wrapper around a char array, with a destructor that frees the memory.

      std::string dwl::convertWstrToStdString(const std::wstring & wStr) {
      //The following code is modified from the examples at http://msmvps.com/blogs/gdicanio/
      //archive/2010/01/04/conversion-between-unicode-utf-16-and-utf-8-in-c-win32.aspx

      if (wStr == L"" || wStr.size()==0) return "";
      //Now, get the size of the required string:
      int origSize = wStr.size();
      origSize++; //For a NULL terminator
      DWORD conversionFlags = 0;
      //First, get the required size:
      int requiredSize = WideCharToMultiByte(CP_ACP, conversionFlags, wStr.c_str(),
      origSize, NULL, 0, NULL, NULL);
      if (requiredSize == 0)
      throw DwlException(_T("Bad Wide String to String conversion"));
      CStrWrap cStr(requiredSize+1);
      int result = WideCharToMultiByte(CP_ACP, conversionFlags, wStr.c_str(),
      origSize, cStr[0], requiredSize, NULL, NULL);
      if (result==0) throw DwlException(_T("Error converting string"));
      *cStr[result] = '\0';
      return std::string(cStr[0]);
      }

      If anyone sees any issues with it, please let me know. Thanks! EDIT - And for std::string to std::wstring:

      std::wstring dwl::convertStdStringToWString(const std::string & str) {
      //This converts a string to a UNICODE string by the method taken on
      //http://www.codeguru.com/forum/archive/index.php/t-231165.html.
      if (str.length() == 0) return L"";
      //Get the required length:
      int unicodeLength = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), 0, 0);
      ++unicodeLength; //Add space for a NULL terminator.
      if (unicodeLength == 0) throw DwlException(_T("Empty conversion"));
      MbStrWrap wStr(unicodeLength);
      int result = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), wStr[0],
      unicodeLength);
      if (result==0) throw DwlException(_T("Error converting string"));
      *wStr[result] = L'\0';
      return std::wstring(wStr[0]);
      }

      My website :: The astronomy of our ancestors: Book :: Videos

      modified on Sunday, January 9, 2011 1:28 AM

      1 Reply Last reply
      0
      • D David ONeil

        It has been awhile since I've looked this deeply into things. Is the following a good way to convert from a wstring to a string?

        std::string dwl::convertWstrToStdString(const std::wstring & wStr) {
        const std::locale & loc = std::wcout.getloc();
        std::string str;
        str.resize(wStr.size()); //If there are cases where the string takes more characters
        //than the wstring, we've got a problem.
        std::string::iterator it = str.begin();
        for (std::wstring::const_iterator wit = wStr.begin(); wit != wStr.end(); ++wit) {
        *it = std::use_facet<std::ctype<wchar_t> >(loc).narrow(*wit);
        ++it;
        }
        return str;
        }

        Or is the 'str.resize' note (or something else) going to bite in the future? Will the str iterator correctly increment if the character it points to will be a Multi Byte character? Should I just use WideCharToMultiByte() and massage it into a std::string? Thanks, David

        My website :: The astronomy of our ancestors: Book :: Videos

        _ Offline
        _ Offline
        _Superman_
        wrote on last edited by
        #3

        You can easily convert if you use an intermediate class like CString or _bstr_t. Using CString -

        wstring wstr(L"Wide String");
        CStringA cstr(wstr.c_str());
        string str(cstr);

        str = "String";
        CStringW wcstr(str.c_str());
        wstr = wcstr;

        Using _bstr_t;

        _bstr_t bstr1(wstr.c_str());
        str = (char*)bstr1;

        _bstr_t bstr2(str.c_str());
        wstr = (wchar_t*)bstr2;

        «_Superman_»  _I love work. It gives me something to do between weekends.

        _Microsoft MVP (Visual C++)

        Polymorphism in C

        D J 2 Replies Last reply
        0
        • _ _Superman_

          You can easily convert if you use an intermediate class like CString or _bstr_t. Using CString -

          wstring wstr(L"Wide String");
          CStringA cstr(wstr.c_str());
          string str(cstr);

          str = "String";
          CStringW wcstr(str.c_str());
          wstr = wcstr;

          Using _bstr_t;

          _bstr_t bstr1(wstr.c_str());
          str = (char*)bstr1;

          _bstr_t bstr2(str.c_str());
          wstr = (wchar_t*)bstr2;

          «_Superman_»  _I love work. It gives me something to do between weekends.

          _Microsoft MVP (Visual C++)

          Polymorphism in C

          D Offline
          D Offline
          David ONeil
          wrote on last edited by
          #4

          Thanks. I wasn't aware of those possibilities.

          My website :: The astronomy of our ancestors: Book :: Videos

          1 Reply Last reply
          0
          • _ _Superman_

            You can easily convert if you use an intermediate class like CString or _bstr_t. Using CString -

            wstring wstr(L"Wide String");
            CStringA cstr(wstr.c_str());
            string str(cstr);

            str = "String";
            CStringW wcstr(str.c_str());
            wstr = wcstr;

            Using _bstr_t;

            _bstr_t bstr1(wstr.c_str());
            str = (char*)bstr1;

            _bstr_t bstr2(str.c_str());
            wstr = (wchar_t*)bstr2;

            «_Superman_»  _I love work. It gives me something to do between weekends.

            _Microsoft MVP (Visual C++)

            Polymorphism in C

            J Offline
            J Offline
            jk chan
            wrote on last edited by
            #5

            i think we need to set correct locale first (setlocale) , right ?

            If u can Dream... U can do it

            _ 1 Reply Last reply
            0
            • J jk chan

              i think we need to set correct locale first (setlocale) , right ?

              If u can Dream... U can do it

              _ Offline
              _ Offline
              _Superman_
              wrote on last edited by
              #6

              If you do not specify a locale, the default will be used.

              «_Superman_»  _I love work. It gives me something to do between weekends.

              _Microsoft MVP (Visual C++)

              Polymorphism in C

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups