Encodage par défaut sur:
- Windows UTF-16.
- Linux UTF-8.
- MacOS UTF-8.
Ce code a deux formes pour convertir std :: string en std :: wstring et std :: wstring en std :: string. Si vous annulez # si WIN32 défini, vous obtenez le même résultat.
1. std :: string à std :: wstring
• MultiByteToWideChar WinAPI
• _mbstowcs_s_l
#if defined WIN32
#include <windows.h>
#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 à 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. Sous Windows, vous devez imprimer unicode à l'aide de 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. Sur le programme principal.
#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. Enfin, vous avez besoin d'un support puissant et complet pour les caractères unicode dans la console.
Je recommande ConEmu et définit comme terminal par défaut sous Windows . Vous devez connecter Visual Studio à ConEmu. N'oubliez pas que le fichier exe de Visual Studio est devenv.exe
Testé sur Visual Studio 2017 avec VC ++; std = c ++ 17.
Résultat