c++中如何进行字符编码转换_c++ utf8转gbk常用方法【详解】
技术百科
裘德小鎮的故事
发布时间:2026-01-16
浏览: 次 Windows平台推荐用MultiByteToWideChar+WideCharToMultiByte双步转换UTF-8→GBK;Linux/macOS用iconv,注意编码名差异;禁用已废弃的std::codecvt系列。
在 C++ 中做 UTF-8 到 GBK 转换,没有标准库原生支持,必须依赖外部库或系统 API。Windows 下最直接可靠的是 MultiByteToWideChar + WideCharToMultiByte 组合;Linux/macOS 则需用 iconv 或 ICU。自己手写查表转换不可取,既不安全也不符合编码规范。
Windows 平台用 WinAPI 双步转换(推荐)
UTF-8 → wchar_t(UTF-16)→ GBK 是 Windows 最稳妥的路径,避免中间编码歧义。注意:CP_UTF8 和 CP_ACP(即系统默认 ANSI 代码页,通常为 GBK)必须明确指定,不能省略。
-
MultiByteToWideChar(CP_UTF8, 0, utf8_str.c_str(), -1, nullptr, 0)先获取所需wchar_t缓冲区长度 - 分配足够空间后再次调用,完成 UTF-8 → UTF-16 转换
-
WideCharToMultiByte(CP_ACP, 0, wstr.data(), -1, nullptr, 0, nullptr, nullptr)获取目标 GBK 字节数 - 再分配
std::vector并执行第二步转换 - 若输入含非法 UTF-8 序列,第一个 API 返回 0,需检查
GetLastError()==ERROR_NO_UNICODE_TRANSLATION
std::string utf8_to_gbk(const std::string& utf8_str) {
if (utf8_str.empty()) return {};
int wlen = MultiByteToWideChar(CP_UTF8, 0, utf8_str.c_str(), -1, nullptr, 0);
if (wlen == 0) return {};
std::vector wstr(wlen);
MultiByteToWideChar(CP_UTF8, 0, utf8_str.c_str(), -1, wstr.data(), wlen);
int len = WideCharToMultiByte(CP_ACP, 0, wstr.data(), -1, nullptr, 0, nullptr, nullptr);
if (len == 0) return {
};
std::vector gbk(len);
WideCharToMultiByte(CP_ACP, 0, wstr.data(), -1, gbk.data(), len, nullptr, nullptr);
return std::string(gbk.data());
}
Linux/macOS 用 iconv(跨平台首选)
iconv 是 POSIX 标准接口,glibc 和 macOS 都内置支持。关键点在于:源编码名必须是 "UTF-8"(不能带横线或空格),目标编码名在 Linux 上常用 "GBK",macOS 则需用 "CP936"(二者等价,但 macOS 的 iconv -l 不识别 GBK)。
- 调用
iconv_open("GBK", "UTF-8")后必须检查返回值是否为(iconv_t)-1 -
iconv()是流式转换,需循环处理,*inbytesleft为 0 才算完成 - 输出缓冲区要预留足够空间(一般按输入字节数 × 2 估算),否则会因
E2BIG失败 - 转换失败时
errno可能是EILSEQ(非法序列)或EINVAL(截断字符),需决定是跳过还是报错
别踩这些坑
很多人试图用 std::codecvt_utf8 或 std::wstring_convert,但它们在 C++17 已被标记为 deprecated,且 GCC/Clang 实现不完整,std::codecvt_byname("zh_CN.GBK") 在多数编译器上根本不可用。还有人把 GBK 当成固定双字节编码硬拆字节,结果遇到 0x81–0xFE 区间外的单字节 ASCII 或高位字节为 0xA1–0xA9 的全角标点就崩溃。
- 不要用
std::codecvt系列——已废弃,行为不可控 - 不要假设 GBK 字符一定是两个字节——ASCII 部分仍是单字节
- 不要忽略 BOM:UTF-8 文件可能带
0xEF 0xBB 0xBF,需提前剥离再传给转换函数 - Windows 下测试时,确保控制台代码页是
936(chcp 936),否则cout输出 GBK 字节会显示乱码
真正麻烦的不是转换逻辑本身,而是错误处理粒度——你要在非法字节处停止、跳过、替换成问号,还是整个字符串拒绝转换?这得看业务场景,库不会替你决定。
# 的是
# 也不
# 很多人
# 第一个
# windows
# 能带
# 已被
# 跳过
# 要在
# mac
# win
# linux
# 循环
# macos
# cos
# c++
# 编码
# 字节
# 标准库
# 字符串
# 接口
# bom
# 则需
# ASCII
# errno
# 全角
# wchar_t
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Win10如何更改开机密码_Windows10登录
- Win11怎么关闭SmartScreen_禁用Wi
- Python函数参数高级用法_默认值与可变参数解析
- Go 中 defer 语句在 goroutine
- 如何使用Golang反射将map转换为struct
- php下载安装包太大怎么下载_分卷压缩下载方法【教
- 如何在Golang中实现微服务负载均衡_Golan
- Win11怎么恢复旧版开始菜单_通过软件还原Win
- Win11怎么快速锁屏_Win11一键锁屏快捷键W
- PhpStorm怎么调试PHP代码_PhpStor
- Go 中 defer 在 goroutine 内部
- How to Properly Use NumPy
- php本地部署支持nodejs吗_php与node
- Win11怎么更改鼠标指针方案_Windows11
- 如何在Golang中使用内置函数_Golangle
- mac怎么分屏_MAC双屏显示与分屏操作技巧【指南
- MAC如何隐藏文件夹及文件_MAC终端命令隐藏与第
- PythonDocker高级项目部署教程_多容器管
- Windows执行文件被SmartScreen拦截
- Win11开机Logo怎么换_Win11自定义启动
- Windows的便笺功能如何使用?(桌面备忘技巧)
- php打包exe怎么传递参数_命令行参数接收方法【
- 微信短链接怎么还原php_用浏览器开发者工具抓包获
- Win11怎么关闭自动维护 Win11禁用系统自动
- 一文教你快速开通网站LOGO图
- PythonPandas数据分析项目教程_时间序列
- Python项目维护经验_长期演进说明【指导】
- Windows如何查看和管理已安装的字体?(字体文
- php中::能用于接口静态方法吗_接口静态方法调用
- Win11怎么设置快速访问主页_Windows11
- php控制舵机角度怎么调_php发送pwm信号控制
- C++如何解析JSON数据?(nlohmann/j
- Windows电脑键盘突然失灵怎么办?(驱动与硬件
- Python高性能计算项目教程_NumPyCyth
- Win11怎么关闭边缘滑动手势_Windows11
- 如何使用Golang反射创建map对象_动态生成键
- php报错怎么查看_定位PHP致命错误与警告的方法
- Win11怎么更改输入法顺序_Win11调整语言首
- 如何在 Go 中判断变量是否为函数类型
- Win10怎样安装Word样式库_Win10安装W
- Win11应用商店下载慢怎么办 Win11更改DN
- Windows10如何更改系统字体大小_Win10
- VSC怎样用终端运行PHP_命令行执行脚本的步骤【
- Win10怎么卸载爱奇艺_Win10彻底卸载爱奇艺
- Mac如何设置动态壁纸?(让桌面动起来)
- C++ static_cast和dynamic_c
- PHP中require语句后直接调用返回对象方法的
- Windows蓝屏BAD_POOL_HEADER故
- php嵌入式日志记录怎么实现_php将硬件数据写入
- Python文本编码与解码_跨平台解析说明【指导】


QQ客服