从 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());
}

 

  1. 计算转换为宽字符(宽字节)所需的缓冲区大小:

    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 表示只返回所需缓冲区大小。

  2. 分配宽字符缓冲区:

    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。

  3. 将 UTF-8 编码的字符串转换为宽字符字符串:

    MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, wstr.get(), len);

    再次调用 MultiByteToWideChar 函数,将 UTF-8 编码的字符串转换为宽字符字符串,并存储在 wstr 缓冲区中。

  4. 计算转换为多字节(GBK)所需的缓冲区大小:

    len = WideCharToMultiByte(CP_ACP, 0, wstr.get(), -1, NULL, 0, NULL, NULL);

    使用 WideCharToMultiByte 函数计算将宽字符字符串转换为多字节(GBK)所需的缓冲区大小。CP_ACP 表示使用系统默认的 ANSI 代码页(通常是 GBK)。

  5. 分配多字节缓冲区:

    std::unique_ptr<char[]> str(new char[len + 1]); memset(str.get(), 0, (len + 1) * sizeof(char));

    使用 std::unique_ptr 智能指针动态分配一个多字节缓冲区,大小为 len + 1memset 函数将缓冲区初始化为 0。

  6. 将宽字符字符串转换为多字节(GBK)字符串:

    WideCharToMultiByte(CP_ACP, 0, wstr.get(), -1, str.get(), len, NULL, NULL);

    再次调用 WideCharToMultiByte 函数,将宽字符字符串转换为多字节(GBK)字符串,并存储在 str 缓冲区中。

  7. 返回转换后的字符串:

    return std::string(str.get());

    将 str 缓冲区中的内容转换为 std::string 并返回。

posted @ 2024-08-01 11:14  素装写淡定  阅读(765)  评论(0)    收藏  举报