How to convert wstring into string?

How to convert wstring into string?

Default encoding on:

  • Windows UTF-16.
  • Linux UTF-8.
  • MacOS UTF-8.

This code have two forms to convert std::string to std::wstring and std::wstring to std::string. If you negate #if defined WIN32, you get the same result.

1. std::string to std::wstring

MultiByteToWideChar WinAPI

_mbstowcs_s_l

#if defined WIN32 #include #endif std::wstring StringToWideString(std::string str) { if (str.empty()) { return std::wstring(); } size_t len = str.length() + 1; std::wstring ret = std::wstring(len, 0); #if defined WIN32 int size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, &str[0], str.size(), &ret[0], len); ret.resize(size); #else size_t size = 0; _locale_t lc = _create_locale(LC_ALL, “en_US.UTF-8”); errno_t retval = _mbstowcs_s_l(&size, &ret[0], len, &str[0], _TRUNCATE, lc); _free_locale(lc); ret.resize(size – 1); #endif return ret; }

2. std::wstring to std::string

WideCharToMultiByte WinAPI

_wcstombs_s_l

std::string WidestringToString(std::wstring wstr) { if (wstr.empty()) { return std::string(); } #if defined WIN32 int size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &wstr[0], wstr.size(), NULL, 0, NULL, NULL); std::string ret = std::string(size, 0); WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &wstr[0], wstr.size(), &ret[0], size, NULL, NULL); #else size_t size = 0; _locale_t lc = _create_locale(LC_ALL, “en_US.UTF-8”); errno_t err = _wcstombs_s_l(&size, NULL, 0, &wstr[0], _TRUNCATE, lc); std::string ret = std::string(size, 0); err = _wcstombs_s_l(&size, &ret[0], size, &wstr[0], _TRUNCATE, lc); _free_locale(lc); ret.resize(size – 1); #endif return ret; }

3. On windows you need to print unicode, using WinAPI.

WriteConsole

#if defined _WIN32 void WriteLineUnicode(std::string s) { std::wstring unicode = StringToWideString(s); WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), unicode.c_str(), unicode.length(), NULL, NULL); std::cout << std::endl; } void WriteUnicode(std::string s) { std::wstring unicode = StringToWideString(s); WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), unicode.c_str(), unicode.length(), NULL, NULL); } void WriteLineUnicode(std::wstring ws) { WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), ws.c_str(), ws.length(), NULL, NULL); std::cout << std::endl; } void WriteUnicode(std::wstring ws) { WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), ws.c_str(), ws.length(), NULL, NULL); }

4. On main program.

#if defined _WIN32 int wmain(int argc, WCHAR ** args) #else int main(int argc, CHAR ** args) #endif { std::string source = u8″ÜüΩωЙ你月曜日naèéøÞǽлљΣæča”; std::wstring wsource = L”ÜüΩωЙ你月曜日naèéøÞǽлљΣæča”; WriteLineUnicode(L”@” + StringToWideString(source) + L”@”); WriteLineUnicode(“@” + WidestringToString(wsource) + “@”); return EXIT_SUCCESS; }

5. Finally You need a powerfull and complete support for unicode chars in console. I recommend ConEmu and set as default terminal on Windows. You need to hook Visual Studio to ConEmu. Remember that Visual Studio’s exe file is devenv.exe

Tested on Visual Studio 2017 with VC++; std=c++17.

Result

Result1

Source

Leave a Reply