在wchar_t和网络字节之间进行转换
C++ - Converting wchar_t to network-byte and back
主要原因是因为我通过socket发送Unicode数据(字节,而不是字符),并且我想确保端序匹配,因为wchar_t是UTF16。
接收程序也是我的另一个程序,所以我知道它是UTF16,并能够做出相应的反应。
这是我目前的算法,有点工作,但有一个奇怪的结果。(这是在同一个应用程序,因为我想学习如何转换它发送它之前)
case WM_CREATE: {
//Convert String to NetworkByte
wchar_t Data[] = L"This is a string";
char* DataA = (char*)Data;
unsigned short uData = htons((unsigned int)DataA);
//Convert String to HostByte
unsigned short hData = ntohs(uData);
DataA = (char*)&hData;
wchar_t* DataW = (wchar_t*)DataA;
MessageBeep(0);
break;
}
结果:쳌쳌쳌쳌쳌곭쳌쳌쳌쳌쳌ē쳌쳌쳌쳌This is a string
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
wchar_t Data[] = L"test";
//Convert String to NetworkByte
for (wchar_t &val : Data) {
if (sizeof(val) == 4) {
val = htonl(val);
}
else if (sizeof(val) == 2) {
val = htons(val);
}
else {
static_assert(sizeof(val) <= 4, "wchar_t is gretter that 32 bit");
}
}
//Convert String to HostByte
for (wchar_t &val : Data) {
if (sizeof(val) == 4) {
val = ntohl(val);
}
else if (sizeof(val) == 2) {
val = ntohs(val);
}
else {
static_assert(sizeof(val) <= 4, "wchar_t is gretter that 32 bit");
}
}
相关文章:
- 在 Rcpp 中的字符串类型之间转换时出错
- r-在Rcpp和C++之间转换矢量(使用Rcpp::as或Rcpp:::wrap)是否会创建一个新的矢量并复制元素
- 在不同类型之间转换常量指针
- 在 3D 骨架系统 DirectX 之间转换
- C++ 如何将用户控件添加到窗体,以便我可以在面板之间转换
- 在 std::u8string 和 std::string 之间转换
- 如何在Unicode/UCS CodePoint和UTF16替代对之间转换
- 在DXGI格式之间转换RGBA数据
- 在两个不动点表达之间转换
- 在函数指针类型之间转换
- 代码的错误答案是在Java Camel案件和C 下划线标识符之间转换的错误答案
- 如何在C 中的不同类之间转换
- 一个关于C++中double和int之间转换的奇怪结果
- 模板类在模板类型之间转换,但也专门化
- 是否有Visual c++编译器在线,以及如何在c++和vs简单代码之间转换
- c/在Unix时间和"Gregorian time"之间转换
- 无法使用iconv在编码之间转换
- 在std::string和std::wstring之间转换的多平台方式
- 我真的应该每次在基元类型之间转换时都使用static_cast吗
- 使用Boost::units在两个量之间转换的最简单方法