在Windows平台的C++开发中,UTF-8和GBK是两种非常常见的字符编码格式,前者多用于跨平台场景和网络传输,后者是Windows系统默认的本地编码之一,二者之间的转换需求十分普遍。借助Windows提供的代码页转换接口,可以快速实现两种编码的相互转换,不需要手动维护复杂的编码映射表。

核心转换接口说明
Windows系统提供了MultiByteToWideChar和WideCharToMultiByte两个核心函数,用于不同代码页之间的字符转换,这两个函数都定义在Windows.h头文件中。
MultiByteToWideChar:将多字节字符串(如UTF-8、GBK)转换为宽字符字符串(UTF-16)WideCharToMultiByte:将宽字符字符串(UTF-16)转换为指定代码页的多字节字符串
UTF-8对应的代码页是CP_UTF8,GBK对应的代码页是936,这两个常量是实现转换的关键参数。
UTF-8转GBK实现步骤
转换流程分为两步:首先将UTF-8字符串转换为UTF-16宽字符,再将UTF-16宽字符转换为GBK编码的多字节字符串。
第一步:UTF-8转UTF-16
先调用MultiByteToWideChar计算需要的宽字符缓冲区大小,再分配内存完成转换。
第二步:UTF-16转GBK
调用WideCharToMultiByte,指定目标代码页为936,将宽字符转换为GBK编码的字符串。
完整代码示例如下:
#include <Windows.h>
#include <string>
#include <vector>
// UTF-8转GBK
std::string UTF8ToGBK(const std::string& utf8Str) {
// 第一步:UTF-8转UTF-16
int wideLen = MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, nullptr, 0);
if (wideLen <= 0) {
return "";
}
std::vector<wchar_t> wideBuf(wideLen);
MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, wideBuf.data(), wideLen);
// 第二步:UTF-16转GBK
int gbkLen = WideCharToMultiByte(936, 0, wideBuf.data(), -1, nullptr, 0, nullptr, nullptr);
if (gbkLen <= 0) {
return "";
}
std::vector<char> gbkBuf(gbkLen);
WideCharToMultiByte(936, 0, wideBuf.data(), -1, gbkBuf.data(), gbkLen, nullptr, nullptr);
return std::string(gbkBuf.data());
}
GBK转UTF-8实现步骤
GBK转UTF-8是上述流程的逆过程,先将GBK转换为UTF-16,再将UTF-16转换为UTF-8。
完整代码示例如下:
#include <Windows.h>
#include <string>
#include <vector>
// GBK转UTF-8
std::string GBKToUTF8(const std::string& gbkStr) {
// 第一步:GBK转UTF-16
int wideLen = MultiByteToWideChar(936, 0, gbkStr.c_str(), -1, nullptr, 0);
if (wideLen <= 0) {
return "";
}
std::vector<wchar_t> wideBuf(wideLen);
MultiByteToWideChar(936, 0, gbkStr.c_str(), -1, wideBuf.data(), wideLen);
// 第二步:UTF-16转UTF-8
int utf8Len = WideCharToMultiByte(CP_UTF8, 0, wideBuf.data(), -1, nullptr, 0, nullptr, nullptr);
if (utf8Len <= 0) {
return "";
}
std::vector<char> utf8Buf(utf8Len);
WideCharToMultiByte(CP_UTF8, 0, wideBuf.data(), -1, utf8Buf.data(), utf8Len, nullptr, nullptr);
return std::string(utf8Buf.data());
}
转换注意事项
- 转换前需要检查输入字符串是否为空,避免无效转换
- 代码页参数不要写错,CP_UTF8对应65001,GBK对应936,错误的代码页会导致转换结果乱码
- 如果转换失败,两个函数都会返回0,可以通过
GetLastError获取具体的错误原因 - 宽字符缓冲区的大小计算需要包含字符串结束符,所以传入-1作为源字符串长度时,计算出的长度已经包含结束符位置
测试示例
可以编写简单的测试代码验证转换效果:
#include <iostream>
int main() {
// 测试UTF-8转GBK
std::string utf8Str = u8"测试编码转换";
std::string gbkStr = UTF8ToGBK(utf8Str);
std::cout << "UTF-8转GBK结果长度:" << gbkStr.length() << std::endl;
// 测试GBK转UTF-8
std::string backUtf8 = GBKToUTF8(gbkStr);
std::cout << "GBK转回UTF-8是否一致:" << (backUtf8 == utf8Str ? "是" : "否") << std::endl;
return 0;
}
上述代码在Windows平台下编译运行后,可以正确完成两种编码的相互转换,转换后的字符串内容保持一致。
C++UTF-8GBK代码页转换Windows_API修改时间:2026-07-05 02:45:24