UTF8 и UTF16 хранят текст совершенно по-другому. Преобразование wchar_t* в char* бессмысленно, это то же самое, что преобразование float в char*.
Используйте WideCharToMultiByte для преобразования UTF16 в UTF8 для отправки в сетевую функцию.
При получении UTF8 от сетевых функций используйте MultiByteToWideChar для обратного преобразования в UTF16, чтобы его можно было использовать в функциях Windows.
Пример:
#include <iostream>
#include <string>
#include <windows.h>
std::string get_utf8(const std::wstring &wstr)
{
if (wstr.empty()) return std::string();
int sz = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], -1, 0, 0, 0, 0);
std::string res(sz, 0);
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], -1, &res[0], sz, 0, 0);
return res;
}
std::wstring get_utf16(const std::string &str)
{
if (str.empty()) return std::wstring();
int sz = MultiByteToWideChar(CP_UTF8, 0, &str[0], -1, 0, 0);
std::wstring res(sz, 0);
MultiByteToWideChar(CP_UTF8, 0, &str[0], -1, &res[0], sz);
return res;
}
int main()
{
std::wstring greek = L"ελληνικά";
std::string utf8 = get_utf8(greek);
//use utf8.data() for network function...
//convert utf8 back to utf16 so it can be displayed in Windows:
std::wstring utf16 = get_utf16(utf8);
MessageBoxW(0, utf16.c_str(), 0, 0);
return 0;
}
Изменить
Еще один пример, показывающий разницу между UTF16 и UTF8. В этом примере рассматриваются байтовые значения UTF16 и UTF8.
Обратите внимание, что для латинского алфавита байты UTF8 и ANSI абсолютно одинаковы.
Также для латинского алфавита есть сходство между UTF8 и UTF16, за исключением того, что в UTF16 есть лишний ноль.
Для греческого и китайского алфавита есть заметная разница.
//(Windows example)
void printbytes_char(const char* ANSI_or_UTF8)
{
const char *bytes = ANSI_or_UTF8;
int len = strlen(bytes);
for (size_t i = 0; i < len; i++)
printf("%02X ", 0xFF & bytes[i]);
printf("\n");
}
void printbytes_wchar_t(const wchar_t* UTF16)
{
//Note, in Windows wchar_t length is 2 bytes
const char *bytes = (const char*)UTF16;
int len = wcslen(UTF16) * 2;
for (size_t i = 0; i < len; i++)
printf("%02X ", 0xFF & bytes[i]);
printf("\n");
}
int main()
{
printbytes_char("ABC");
printbytes_char(u8"ABC");
printbytes_wchar_t(L"ABC");
printbytes_char(u8"ελληνικά");
printbytes_wchar_t(L"ελληνικά");
printbytes_char(u8"汉字/漢字");
printbytes_wchar_t(L"汉字/漢字");
return 0;
}
Вывод:
"ABC":
41 42 43 //ANSI
41 42 43 //UTF8
41 00 42 00 43 00 //UTF16 (this is little endian, bytes are swapped)
"ελληνικά"
CE B5 CE BB CE BB CE B7 CE BD CE B9 CE BA CE AC //UTF8
B5 03 BB 03 BB 03 B7 03 BD 03 B9 03 BA 03 AC 03 //UTF16
"汉字/漢字"
E6 B1 89 E5 AD 97 2F E6 BC A2 E5 AD 97 //UTF8
49 6C 57 5B 2F 00 22 6F 57 5B //UTF16
person
Barmak Shemirani
schedule
29.10.2016
MultiByteToWideCharиWideCharToMultiByteдля преобразования между UTF16 (стандарт Windows) и UTF8 (дружественный к сети) Пример - person Barmak Shemirani   schedule 29.10.2016static_castбольшую часть времени вместо массивов в стиле C; они предотвращают такую путаницу. - person Asu   schedule 29.10.2016L"盘"- это UTF16wchar_t, он будет преобразован в UTF8u8"盘"(хранится вchar). Это один и тот же текст, но хранится по-разному. Сетевые функции ожидают UTF8 - person Barmak Shemirani   schedule 29.10.2016