How to convert wstring into string?

前端 未结 17 1946
北海茫月
北海茫月 2020-11-22 13:10

The question is how to convert wstring to string?

I have next example :

#include 
#include 

int main()
{
    std::wstr         


        
相关标签:
17条回答
  • 2020-11-22 13:20
    #include <boost/locale.hpp>
    namespace lcv = boost::locale::conv;
    
    inline std::wstring fromUTF8(const std::string& s)
    { return lcv::utf_to_utf<wchar_t>(s); }
    
    inline std::string toUTF8(const std::wstring& ws)
    { return lcv::utf_to_utf<char>(ws); }
    
    0 讨论(0)
  • 2020-11-22 13:20

    I am using below to convert wstring to string.

    std::string strTo;
    char *szTo = new char[someParam.length() + 1];
    szTo[someParam.size()] = '\0';
    WideCharToMultiByte(CP_ACP, 0, someParam.c_str(), -1, szTo, (int)someParam.length(), NULL, NULL);
    strTo = szTo;
    delete szTo;
    
    0 讨论(0)
  • 2020-11-22 13:21

    Besides just converting the types, you should also be conscious about the string's actual format.

    When compiling for Multi-byte Character set Visual Studio and the Win API assumes UTF8 (Actually windows encoding which is Windows-28591 ).
    When compiling for Unicode Character set Visual studio and the Win API assumes UTF16.

    So, you must convert the string from UTF16 to UTF8 format as well, and not just convert to std::string.
    This will become necessary when working with multi-character formats like some non-latin languages.

    The idea is to decide that std::wstring always represents UTF16.
    And std::string always represents UTF8.

    This isn't enforced by the compiler, it's more of a good policy to have. Note the string prefixes I use to define UTF16 (L) and UTF8 (u8).

    To convert between the 2 types, you should use: std::codecvt_utf8_utf16< wchar_t>

    #include <string>
    
    #include <codecvt>
    
    int main()
    {
    
        std::string original8 = u8"הלו";
    
        std::wstring original16 = L"הלו";
    
        //C++11 format converter
        std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
    
        //convert to UTF8 and std::string
        std::string utf8NativeString = convert.to_bytes(original16);
    
        std::wstring utf16NativeString = convert.from_bytes(original8);
    
        assert(utf8NativeString == original8);
        assert(utf16NativeString == original16);
    
        return 0;
    }
    
    0 讨论(0)
  • 2020-11-22 13:22

    I believe the official way is still to go thorugh codecvt facets (you need some sort of locale-aware translation), as in

    resultCode = use_facet<codecvt<char, wchar_t, ConversionState> >(locale).
      in(stateVar, scratchbuffer, scratchbufferEnd, from, to, toLimit, curPtr);
    

    or something like that, I don't have working code lying around. But I'm not sure how many people these days use that machinery and how many simply ask for pointers to memory and let ICU or some other library handle the gory details.

    0 讨论(0)
  • 2020-11-22 13:23

    At the time of writing this answer, the number one google search for "convert string wstring" would land you on this page. My answer shows how to convert string to wstring, although this is NOT the actual question, and I should probably delete this answer but that is considered bad form. You may want to jump to this StackOverflow answer, which is now higher ranked than this page.


    Here's a way to combining string, wstring and mixed string constants to wstring. Use the wstringstream class.

    #include <sstream>
    
    std::string narrow = "narrow";
    std::wstring wide = "wide";
    
    std::wstringstream cls;
    cls << " abc " << narrow.c_str() << L" def " << wide.c_str();
    std::wstring total= cls.str();
    
    0 讨论(0)
  • 2020-11-22 13:24

    I spent many sad days trying to come up with a way to do this for C++17, which deprecated code_cvt facets, and this is the best I was able to come up with by combining code from a few different sources:

    setlocale( LC_ALL, "en_US.UTF-8" ); //Invoked in main()
    
    std::string wideToMultiByte( std::wstring const & wideString )
    {
         std::string ret;
         std::string buff( MB_CUR_MAX, '\0' );
    
         for ( wchar_t const & wc : wideString )
         {
             int mbCharLen = std::wctomb( &buff[ 0 ], wc );
    
             if ( mbCharLen < 1 ) { break; }
    
             for ( int i = 0; i < mbCharLen; ++i ) 
             { 
                 ret += buff[ i ]; 
             }
         }
    
         return ret;
     }
    
     std::wstring multiByteToWide( std::string const & multiByteString )
     {
         std::wstring ws( multiByteString.size(), L' ' );
         ws.resize( 
             std::mbstowcs( &ws[ 0 ], 
                 multiByteString.c_str(), 
                 multiByteString.size() ) );
    
         return ws;
     }
    

    I tested this code on Windows 10, and at least for my purposes, it seems to work fine. Please don't lynch me if this doesn't consider some crazy edge cases that you might need to handle, I'm sure someone with more experience can improve on this! :-)

    Also, credit where it's due:

    Adapted for wideToMultiByte()

    Copied for multiByteToWide

    0 讨论(0)
提交回复
热议问题