从 UTF-8 编码到 GBK 编码的转换,解决中文在日志里显示乱码
从 UTF-8 编码到 GBK 编码的转换,通过中间步骤先将 UTF-8 转换为宽字符,再将宽字符转换为 GBK。
std::string Utf8ToGbk(const std::string& utf8) { int len = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, NULL, 0); std::unique_ptr<wchar_t[]> wstr(new wchar_t[len + 1]); memset(wstr.get(), 0, (len + 1) * sizeof(wchar_t)); MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, wstr.get(), len); len = WideCharToMultiByte(CP_ACP, 0, wstr.get(), -1, NULL, 0, NULL, NULL); std::unique_ptr<char[]> str(new char[len + 1]); memset(str.get(), 0, (len + 1) * sizeof(char)); WideCharToMultiByte(CP_ACP, 0, wstr.get(), -1, str.get(), len, NULL, NULL); return std::string(str.get()); }
-
计算转换为宽字符(宽字节)所需的缓冲区大小:
int len = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, NULL, 0);这里使用
MultiByteToWideChar函数计算将 UTF-8 编码的字符串utf8转换为宽字符(wchar_t)所需的缓冲区大小。CP_UTF8指定了源字符串的编码格式是 UTF-8。utf8.c_str()返回指向字符串内容的指针。-1表示处理到字符串的结尾(包括终止符)。NULL和0表示只返回所需缓冲区大小。 -
分配宽字符缓冲区:
std::unique_ptr<wchar_t[]> wstr(new wchar_t[len + 1]); memset(wstr.get(), 0, (len + 1) * sizeof(wchar_t));使用
std::unique_ptr智能指针动态分配一个宽字符缓冲区,大小为len + 1,以确保有足够的空间存储转换后的宽字符字符串以及终止符。memset函数将缓冲区初始化为 0。 -
将 UTF-8 编码的字符串转换为宽字符字符串:
MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, wstr.get(), len);再次调用
MultiByteToWideChar函数,将 UTF-8 编码的字符串转换为宽字符字符串,并存储在wstr缓冲区中。 -
计算转换为多字节(GBK)所需的缓冲区大小:
len = WideCharToMultiByte(CP_ACP, 0, wstr.get(), -1, NULL, 0, NULL, NULL);使用
WideCharToMultiByte函数计算将宽字符字符串转换为多字节(GBK)所需的缓冲区大小。CP_ACP表示使用系统默认的 ANSI 代码页(通常是 GBK)。 -
分配多字节缓冲区:
std::unique_ptr<char[]> str(new char[len + 1]); memset(str.get(), 0, (len + 1) * sizeof(char));使用
std::unique_ptr智能指针动态分配一个多字节缓冲区,大小为len + 1。memset函数将缓冲区初始化为 0。 -
将宽字符字符串转换为多字节(GBK)字符串:
WideCharToMultiByte(CP_ACP, 0, wstr.get(), -1, str.get(), len, NULL, NULL);再次调用
WideCharToMultiByte函数,将宽字符字符串转换为多字节(GBK)字符串,并存储在str缓冲区中。 -
返回转换后的字符串:
return std::string(str.get());将
str缓冲区中的内容转换为std::string并返回。

浙公网安备 33010602011771号