0

0

c++如何将utf8转为gbk_c++编码转换方法【实战】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-01-24 13:00:02

|

938人浏览过

|

来源于php中文网

原创

std::codecvt 因 C++17 弃用、C++20 移除且跨平台支持差(GCC/Clang 崩溃、MSVC 依赖系统 locale)而不可用;推荐 iconv(跨平台稳定)或 Windows 原生 API(MultiByteToWideChar + WideCharToMultiByte),禁用 wstring_convert 和自制查表法。

c++如何将utf8转为gbk_c++编码转换方法【实战】

为什么 std::codecvt 在 C++17 被弃用还总被推荐?

因为它是标准库中唯一曾原生支持 UTF-8 ↔ GBK 转换的机制,但实际项目中基本不能用:std::codecvt_utf8_utf16 只处理 UTF-16,std::codecvt_byname("zh_CN.GB18030") 在 GCC/Clang 上常崩溃或返回空结果,MSVC 虽部分支持却要求系统 locale 已安装 GBK 区域设置(Linux/macOS 通常不满足)。更关键的是——C++17 明确标记其为 deprecated,C++20 彻底移除。别再试了。

iconv 是最稳的跨平台方案

Linux/macOS 自带,Windows 可通过 win-iconv 或 MSYS2 的 libiconv 支持。核心是三步:初始化、转换、清理。注意 iconv() 修改输入/输出指针,必须用临时变量保存原始地址。

常见错误现象:iconv() 返回 -1 且 errno == EILSEQ —— 输入含非法 UTF-8 字节序列;errno == EINVAL —— 输入未完整字符结尾(如截断的 UTF-8);errno == E2BIG —— 输出缓冲区不够(需扩容重试)。

实操建议:

立即学习C++免费学习笔记(深入)”;

ReRoom AI
ReRoom AI

专为室内设计打造的AI渲染工具,可以将模型图、平面图、草图、照片转换为高质量设计效果图。

下载
  • iconv_open("GBK", "UTF-8") 必须检查返回值是否为 (iconv_t)(-1),失败时直接 return
  • 输出缓冲大小建议按输入字节数 × 2 预估(GBK 单字符最多 2 字节,UTF-8 最多 4 字节,但中文通常 1:1 或 1:2)
  • 转换后记得 iconv_close(),否则内存泄漏
  • Windows 下若用 MinGW 编译,链接加 -liconv;VS 用户需额外配置头文件与 .lib

Windows 平台可直接用 MultiByteToWideChar + WideCharToMultiByte

绕过第三方依赖,纯 Win32 API。先 UTF-8 → UTF-16(用 CP_UTF8),再 UTF-16 → GBK(用 CP_ACP 或显式 936)。注意:CP_ACP 依赖系统默认 ANSI 代码页,中文 Windows 默认是 GBK(即 CP936),但非中文系统会出错,所以硬编码 936 更可靠。

关键细节:

  • MultiByteToWideChar(CP_UTF8, ...) 第二个参数若传 MB_ERR_INVALID_CHARS,遇到非法 UTF-8 会失败;不传则静默跳过(慎用)
  • 两次调用都需先传 NULL 获取目标缓冲长度,再分配内存,避免溢出
  • 返回的 GBK 字节数不含终止 \0,如需 C 字符串要手动补
  • 该方法在 Wine 或非 Windows 环境完全不可用,勿写成跨平台假象

别碰 std::wstring_convert 和自制查表法

std::wstring_convert 依赖已废弃的 std::codecvt,GCC 7+ 编译直接报错;自制 UTF-8 解码 + GBK 编码查表看似可控,但 GBK 不是简单映射——它包含区位码、造字区、兼容 ASCII 等复杂规则,且微软 GBK(CP936)和国标 GB18030 子集有细微差异。已有成熟库,重复造轮子只会引入乱码、越界、安全漏洞。

真正要注意的其实是边界:输入是否以 BOM 开头(UTF-8 BOM 是可选的 \xEF\xBB\xBF,GBK 无 BOM)、是否含控制字符、是否混用半宽/全宽标点。这些不会在转换函数里报错,但会导致下游解析失败——得在转换前做清洗或转换后校验字节数与原始长度比。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

233

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

437

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

278

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1492

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

622

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

572

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

566

2024.04.29

c++空格相关教程合集
c++空格相关教程合集

本专题整合了c++空格相关教程,阅读专题下面的文章了解更多详细内容。

0

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.7万人学习

Git 教程
Git 教程

共21课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号