C++ UTF-8与GBK字符的转换 —基于Linux 虚拟机 (iconv_open iconv)
1、UTF-8 和 GBK 的区别
GBK:通常简称 GB (“国标”汉语拼音首字母),GBK 包含全部中文字符。
UTF-8 :是一种国际化的编码方式,包含了世界上大部分的语种文字(简体中文字、繁体中文字、英文、日文、韩文等语言),也兼容 ASCII 码。UTF-8 则包含全世界所有国家需要用到的字符。
2、UTF-8 和 GBK 的作用:
这两种编码方式的的作用就是,在不同的应用环境中使用特定的编码方式
如果输入字符编码是UTF-8,如果想要将信息转换为汉字呈现在显示器上,就必须进行GBK转码操作,才能在显示屏上看到信息;
如果输入字符编码是GBK,如果想要在系统操作中让嵌入式设备或者编程环境认知它,就需要进行UTF-8转码操作。
3、UTF-8 和 GBK 之间如何转换:
在字符转换的过程中,二者不可以直接进行转换,必须借助于unicode
3.1、UTF-8转GBK
UTF-8——unicode——GBK
3.2、GBK转UTF-8
GBK——unicode——UTF-8
4、UTF-8 转GBK ——C++代码:
4.1、引入Win32
因为linux是32位的,所以首先需要引入Winsows.h库,附带引入iconv.h库
#include<iostream>
#include<string>
#include<string.h>
#ifdef _WIN32
#include<Windows.h>
#else
#include<iconv.h>
#endif // _WIN32
using namespace std;
#ifndef _WIN32
4.2、定义函数
static size_t Convert(char* from_cha, char* to_char, char* in, size_t inlen, char* out, size_t outlen)
{//转换上下文iconv_t cd;cd = iconv_open(to_char, from_cha);if (cd == 0){return -1;}memset(out, 0, outlen);char** pin = ∈char** pout = &out;//返回转换字节数的数量,但是转GBK的时候经常不正确 >=0就是成功size_t re = iconv(cd, pin, &inlen, pout, &outlen);if (cd != 0){iconv_close(cd);}cout << "re=" <<(int) re << endl;return re;
}
4.2.1、iconv库介绍
iconv库——linux的转换字符编码库
iconv_open()——作用:从字符编码from_char转换为to_char
iconv_open(to_char, from_cha);
iconv_close():—— 关闭参数所指定的转换描述符
iconv_close(cd);
memset库——memset是C库函数
memset(out, 0, outlen);
- out -- 指向要填充的内存块。
- 0 -- 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
- outlen -- 要被设置为该值的字符数。
4.3、统计转换后的字节数 使用内置函数
现在格式是UTF8,即CP_UTF8.
int len = MultiByteToWideChar(CP_UTF8, //转换的格式0, //默认的转换方式data, //输入的字节-1, //输入的字符串大小 -1找\0结束 自己去算0, //输出(不输出,统计转换后的字节数)0 //输出的空间大小);
4.4、用wtring存储数据,并为其分配大小
wstring udata; //用wstring存储的
udata.resize(len);//分配大小
4.5、UTF-8转unicode。
将数据写进去,将数据强转为wchar_t类型,适用于windows和linux。
MultiByteToWideChar(CP_UTF8, 0, data, -1, (wchar_t*)udata.data(), len);
4.6、unicode转GBK。
现在格式转成GBK,即CP_ACP。和UTF-8的参数数量不一样哦
len = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)udata.data(), -1, 0, 0,0, //失败替代默认字符0 //是否使用默认替代 0 false);
4.7、配置字符大小,转成GBK
utf8.resize(len);
WideCharToMultiByte(CP_ACP, 0, (wchar_t*)udata.data(), -1, (char*)utf8.data(), len, 0, 0);
4.8、 UTF-8转GBK完整代码
其他都是一样的,只不过加了
#ifdef _WIN32
......
.....
#else
//linuxre.resize(1024);int inlen = strlen(data);cout << "inlen=" << inlen << endl;Convert((char*)"utf-8", (char*)"gbk", (char*)data, inlen, (char*)re.data(), re.size());int outlen = strlen(re.data());re.resize(outlen);
#endif
#endif
string UTF8ToGBK2(const char* data)
{string re = "";//1、UTF8 先要转为unicode windows utf16
#ifdef _WIN32//1.1 统计转换后的字节数int len = MultiByteToWideChar(CP_UTF8, //转换的格式0, //默认的转换方式data, //输入的字节-1, //输入的字符串大小 -1找\0结束 自己去算0, //输出(不输出,统计转换后的字节数)0 //输出的空间大小);if (len <= 0){return re;}wstring udata; //用wstring存储的udata.resize(len);//分配大小//开始写进去MultiByteToWideChar(CP_UTF8, 0, data, -1, (wchar_t*)udata.data(), len);//2 unicode 转 GBK 转成unicodelen = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)udata.data(), -1, 0, 0,0, //失败替代默认字符0 //是否使用默认替代 0 false);if (len <= 0){return re;}re.resize(len);WideCharToMultiByte(CP_ACP, 0, (wchar_t*)udata.data(), -1, (char*)re.data(), len, 0, 0);
#elsere.resize(1024);int inlen = strlen(data);cout << "inlen=" << inlen << endl;Convert((char*)"utf-8", (char*)"gbk", (char*)data, inlen, (char*)re.data(), re.size());int outlen = strlen(re.data());re.resize(outlen);
#endifreturn re;
}
5、GBK 转 UTF-8 ——C++代码:
5.1、统计转换后的字节数
//1.1 统计转换后的字节数int len = MultiByteToWideChar(CP_ACP, //转换的格式0, //默认的转换方式data, //输入的字节-1, //输入的字符串大小 -1找\0结束 自己去算0, //输出(不输出,统计转换后的字节数)0 //输出的空间大小);
5.2、用wstring存储数据,并为其分配大小
wstring udata; //用wstring存储的
udata.resize(len);//分配大小
5.3、GBK转unicode
//开始写进去MultiByteToWideChar(CP_ACP, 0, data, -1, (wchar_t*)udata.data(), len);
5.4、unicode转UTF-8
//2 unicode 转 utf8len = WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)udata.data(), -1, 0, 0,0, //失败替代默认字符0 //是否使用默认替代 0 false);
5.5、配置字符大小,转成UTF-8
GBK.resize(len);
WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)udata.data(), -1, (char*)GBK.data(), len, 0, 0);
5.6、GBK 转UTF-8 完整代码
其他都是一样的,只不过加了
#ifdef _WIN32
.....
.....
#else
//linuxre.resize(1024);int inlen = strlen(data);Convert((char*)"gbk", (char*)"utf-8", (char*)data, inlen, (char*)re.data(), re.size());int outlen = strlen(re.data());re.resize(outlen);
#endif
string GBKToUTF82(const char* data)
{string re = "";
#ifdef _WIN32//1、GBK转unicode//1.1 统计转换后的字节数int len = MultiByteToWideChar(CP_ACP, //转换的格式0, //默认的转换方式data, //输入的字节-1, //输入的字符串大小 -1找\0结束 自己去算0, //输出(不输出,统计转换后的字节数)0 //输出的空间大小);if (len <= 0){return re;}wstring udata; //用wstring存储的udata.resize(len);//分配大小//开始写进去MultiByteToWideChar(CP_ACP, 0, data, -1, (wchar_t*)udata.data(), len);//2 unicode 转 utf8 转成unicodelen = WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)udata.data(), -1, 0, 0,0, //失败替代默认字符0 //是否使用默认替代 0 false);if (len <= 0){return re;}re.resize(len);WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)udata.data(), -1, (char*)re.data(), len, 0, 0);
#elsere.resize(1024);int inlen = strlen(data);Convert((char*)"gbk", (char*)"utf-8", (char*)data, inlen, (char*)re.data(), re.size());int outlen = strlen(re.data());re.resize(outlen);
#endifreturn re;
}
6、linux虚拟机测试
6.1、创建文件夹
mkdir test_GBK_UTF-8
6.2、进入文件夹
cd test_GBK_UTF-8

6.3、创建test_GBK_UTF-8.cpp文件
vim test_GBK_UTF-8.cpp
将刚才代码放进去,按下esc键盘+输入 :wq (有一个:呦),回车


6.4、输入
//g++就是运行环境是C++
g++ test_GBK_UTF-8.cpp -o test_GBK_UTF-8

6.5、执行
./test_GBK_UTF-8
6.6、结果

如果不转码,会输出乱码
7、完整代码——基于linux
//GBK转utf-8
#include<iostream>
#include<string>
#include<string.h>
#ifdef _WIN32
#include<Windows.h>
#else
#include<iconv.h>
#endif // _WIN32
using namespace std;
#ifndef _WIN32
static size_t Convert(char* from_cha, char* to_char, char* in, size_t inlen, char* out, size_t outlen)
{//转换上下文iconv_t cd;cd = iconv_open(to_char, from_cha);if (cd == 0){return -1;}memset(out, 0, outlen);char** pin = ∈char** pout = &out;//返回转换字节数的数量,但是转GBK的时候经常不正确 >=0就是成功size_t re = iconv(cd, pin, &inlen, pout, &outlen);if (cd != 0){iconv_close(cd);}cout << "re=" <<(int) re << endl;return re;
}
#endif // !_WIN32string UTF8ToGBK(const char* data)
{string re = "";//1、UTF8 先要转为unicode windows utf16
#ifdef _WIN32//1.1 统计转换后的字节数int len = MultiByteToWideChar(CP_UTF8, //转换的格式0, //默认的转换方式data, //输入的字节-1, //输入的字符串大小 -1找\0结束 自己去算0, //输出(不输出,统计转换后的字节数)0 //输出的空间大小);if (len <= 0){return re;}wstring udata; //用wstring存储的udata.resize(len);//分配大小//开始写进去MultiByteToWideChar(CP_UTF8, 0, data, -1, (wchar_t*)udata.data(), len);//2 unicode 转 GBK 转成unicodelen = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)udata.data(), -1, 0, 0,0, //失败替代默认字符0 //是否使用默认替代 0 false);if (len <= 0){return re;}re.resize(len);WideCharToMultiByte(CP_ACP, 0, (wchar_t*)udata.data(), -1, (char*)re.data(), len, 0, 0);
#elsere.resize(1024);int inlen = strlen(data);cout << "inlen=" << inlen << endl;Convert((char*)"utf-8", (char*)"gbk", (char*)data, inlen, (char*)re.data(), re.size());int outlen = strlen(re.data());re.resize(outlen);
#endifreturn re;
}string GBKToUTF8(const char* data)
{string re = "";
#ifdef _WIN32//1、GBK转unicode//1.1 统计转换后的字节数int len = MultiByteToWideChar(CP_ACP, //转换的格式0, //默认的转换方式data, //输入的字节-1, //输入的字符串大小 -1找\0结束 自己去算0, //输出(不输出,统计转换后的字节数)0 //输出的空间大小);if (len <= 0){return re;}wstring udata; //用wstring存储的udata.resize(len);//分配大小//开始写进去MultiByteToWideChar(CP_ACP, 0, data, -1, (wchar_t*)udata.data(), len);//2 unicode 转 utf8 转成unicodelen = WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)udata.data(), -1, 0, 0,0, //失败替代默认字符0 //是否使用默认替代 0 false);if (len <= 0){return re;}re.resize(len);WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)udata.data(), -1, (char*)re.data(), len, 0, 0);
#elsere.resize(1024);int inlen = strlen(data);Convert((char*)"gbk", (char*)"utf-8", (char*)data, inlen, (char*)re.data(), re.size());int outlen = strlen(re.data());re.resize(outlen);
#endifreturn re;return re;
}int main()
{std::cout << "Hello World! 测试\n";//1、测试utf-8转GBK//cout << UTF8ToGBK(u8"测试UTF-8转GBK") << endl;string in = u8"测试UTF-8转GBK";cout << "输入 utf=" << in << endl;string gbk = UTF8ToGBK2(in.c_str());cout << "gbk=" << gbk << endl;cout << GBKToUTF82(gbk.c_str()) << endl;system("pause");return 0;
}
相关文章:
C++ UTF-8与GBK字符的转换 —基于Linux 虚拟机 (iconv_open iconv)
1、UTF-8 和 GBK 的区别 GBK:通常简称 GB (“国标”汉语拼音首字母),GBK 包含全部中文字符。 UTF-8 :是一种国际化的编码方式,包含了世界上大部分的语种文字(简体中文字、繁体中文字、英文、…...
云原生十二问
一、什么是云原生? 云原生是在云计算环境中构建、部署和管理现代应用程序的软件方法。现代企业希望构建高度可扩展、灵活且具有弹性的应用程序,可以快速更新以满足客户需求。为此,他们使用现代工具和技术,这些工具和技术本质上支…...
K8Spod组件
一个pod能包含几个容器 一个pause容器(基础容器/父容器/根容器) 一个或者多个应用容器(业务容器) 通常一个Pod最好只包含一个应用容器,一个应用容器最好也只运行一个业务进程。 同一个Pod里的容器都是运行在同一个node节点上的,并且共享 net、…...
clickhouse-client INSERT CSV/TSV时跳过错误行
clickhouse-client INSERT CSV/TSV时跳过错误行 在使用clickhouse-client向ck中导入csv文件时,当csv中有个别行数据格式错误时,整个文件就插入失败了,经常会导致丢数据。 经过一番搜索,发现ck提供了两个参数可以跳过错误行&#x…...
直流稳压电源电路
一、稳压电源的技术指标及对稳压电源的要求 稳压电源的技术指标可以分为两大类:一类是特性指标,如输出电压、输出电滤及电压调节范围;另一类是质量指标,反映一个稳压电源的优劣,包括稳定度、等效内阻(输出电阻&#x…...
记录爬虫编写步骤
本文讲解 Python 爬虫实战案例:抓取百度贴吧(https://tieba.baidu.com/)页面,比如 Python爬虫吧、编程吧,只抓取贴吧的前 5 个页面即可。今天一个毕业学生问到一个问题:不清楚编写爬虫的步骤,不…...
SpringBoot配置Swagger2与Swagger3
swagger是什么? 在平时开发中,一个好的API文档可以减少大量的沟通成本,还可以帮助新加入项目的同事快速上手业务。大家都知道平时开发时,接口变化总是很多,有了变化就要去维护,也是一件比较头大的事情。尤…...
C/C++ 枚举
目录 枚举概述 枚举的使用 枚举的大小计算 枚举的优点 C语言中的自定义类型有:结构 位段 枚举 联合 枚举概述 枚举顾名思义就是一一列举,把可能的取值一一列举。 比如我们现实生活中:一周的星期一到星期日是有限的7天,…...
P12 音视频复合流——TS流讲解
前言 从本章开始我们将要学习嵌入式音视频的学习了 ,使用的瑞芯微的开发板 🎬 个人主页:ChenPi 🐻推荐专栏1: 《C_ChenPi的博客-CSDN博客》✨✨✨ 🔥 推荐专栏2: 《Linux C应用编程(概念类)_C…...
三维重建 3D Gaussian Splatting:实时的神经场渲染
目录 概念理解三维高斯喷洒 渲染实例 依赖项: 编译报错: 预训练模型 13G:...
Django Web框架
1、创建PyCharm项目 2、安装框架 pip install django4.2.0 3、查看安装的包列表 4、使用命令创建django项目 django-admin startproject web 5、目录结构 6、运行 cd web python manage.py runserver7、初始化后台登录的用户名密码 执行数据库迁移生成数据表 python man…...
ARCGIS PRO SDK GeometryEngine.Intersection的GeometryDimensionType 枚举
描述几何对象的维度。与 GeometryEngine.Intersection 一起使用。 成员描述EsriGeometry0Dimension零维(点或多点)。EsriGeometry1Dimension一维(折线)。EsriGeometry2Dimension二维(多边形或包络)。Es…...
Web网页开发-CSS层叠样式表1-笔记
1.CSS的引入方式 (1)内嵌式:把style双标签写在head标签里面,可以影响同种标签 (2)行内式:把style写在标签内部,只能影响当前标签 (3)外链式:创建css文件,使用link将html文件和css文件连接起来 (4)导入式&am…...
如何预防变种.halo勒索病毒感染您的计算机?
尊敬的读者: 在数字时代,威胁网络安全的.halo勒索病毒日益猖狂。本文将深入介绍.halo病毒的攻击方式,以及针对被加密文件的恢复方法和预防措施。在面对被勒索病毒攻击导致的数据文件加密问题时,技术支持显得尤为重要,…...
短网址的新玩法,短到只剩域名
短网址大家应该都不陌生了,一句话就可以解释清楚,把一串很长的网址缩短到只有几个字符依然可以正常访问,缩短之后会更加简洁美观。 那大家见过的短网址一般长啥样呢,比如t.cn/xxxxx、dwz.cn/xxxxx、c1ns.cn/xxxxx。这些短网址都有…...
FA2016AA (MHz范围晶体单元超小型低轮廓贴片) 汽车
随着科技的不断发展,智能汽车逐渐成为人们出行的首选。而其中,频率范围在19.2 MHz ~ 54 MHz的晶体单元超小型低轮廓贴片(FA2016AA)为汽车打造更智能、更舒适、更安全的出行体验。FA2016AA贴片的外形尺寸为2.0 1.6 0.5 mm&#x…...
【设计模式之美】面向对象分析方法论与实现(一):需求分析方法论
文章目录 一. 需求举例二. 对案例进行需求分析1. 第一轮基础分析2. 第二轮分析优化3. 第三轮分析优化4. 第四轮分析优化5. 最终确定需求 三. 小结 本文主要描述: 面向对象的需求分析方法论 一. 需求举例 假设,你正在参与开发一个微服务。微服务通过 HTT…...
MySQL视图索引执行计划相关十五道面试题分享
目录 一. 视图 1.1 含义 1.2 操作 创建视图 修改视图 删除视图 查看视图 二. 索引 2.1 什么是索引 2.2 为什么要使用索引 2.3 优点 2.4 缺点 2.5 何时不适用索引 2.6 索引何时失效 三. 执行计划 3.1 什么是执行计划 3.2 执行计划的作用 四. 面试题 表结构 …...
vue绑定背景颜色或背景图片 和 nuxtjs动态设置background-image:
v-bind绑定样式表: ---------------------------------------------------------------------------------------------------- HTML写法: <div class"myItem" style"text-align:center; background-image:url(); background-size:auto 100% ;ba…...
案例099:基于微信小程序的外卖小程序的研究与开发
文末获取源码 开发语言:Java 框架:SSM JDK版本:JDK1.8 数据库:mysql 5.7 开发软件:eclipse/myeclipse/idea Maven包:Maven3.5.4 小程序框架:uniapp 小程序开发软件:HBuilder X 小程序…...
解密VideoDownloadHelper:开源浏览器插件的智能视频提取技术
解密VideoDownloadHelper:开源浏览器插件的智能视频提取技术 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 当你在浏览微博、秒拍…...
天学网口碑好不好?2026年最新用户实测反馈给你答案
作为深耕教育数字化落地领域5年的从业者,最近后台收到不少公立校电教组老师、学生家长的提问:主打AI英语教学的天学网口碑到底怎么样?刚好我们团队刚做完2026年第一季度的英语教育数字化工具落地效果调研,结合一手实测数据给大家客…...
83.人工智能实战:RAG 表格问答怎么做?从前期发现“表格被切碎”到结构化解析、行列索引与答案校验
人工智能实战:RAG 表格问答怎么做?从前期发现“表格被切碎”到结构化解析、行列索引与答案校验 一、问题场景:Word 文档能答,Excel 表格一问就错 很多企业知识库不只有 Word 和 PDF,还有大量表格: 1. 报销标准表 2. 产品价格表 3. 客户等级表 4. SLA 服务等级表 5. 部门…...
【2026年阿里巴巴集团暑期实习- 5月16日-算法岗-第二题- 坏掉的键盘】(题目+思路+JavaC++Python解析+在线测试)
题目内容 小明准备输入一个仅由小写英文字母组成的字符串,但他的键盘在一开始就有且仅有一个按键失灵,导致该字母在原串中的所有出现都没有被输入,最终得到的字符串为 sss。小明还告诉你:原本要输入的完整字符串中任意相邻两个字符都不相同。 请你计算,对于每一个可能的…...
成本优化策略:降低云资源支出
成本优化策略:降低云资源支出 一、成本优化策略概述 1.1 成本优化策略的定义 成本优化策略是指通过各种技术和管理手段,降低云资源支出的策略和方法。它包括资源优化、成本监控、预算管理和采购策略等方面。 1.2 成本优化策略的价值 成本降低:…...
云原生安全工具:保护云原生环境
云原生安全工具:保护云原生环境 一、云原生安全工具概述 1.1 云原生安全工具的定义 云原生安全工具是指专为云原生环境设计的安全工具和解决方案。它们用于保护容器、Kubernetes集群、微服务和Serverless应用的安全。 1.2 云原生安全工具的价值 安全防护:…...
大语言模型可靠性监测与压缩的谱方法研究
1. 大语言模型可靠性监测与压缩的谱方法研究概述在深度学习领域,大语言模型(LLM)和视觉语言模型(VLM)的可靠性问题与计算效率挑战日益凸显。模型幻觉(生成与输入无关或错误的内容)和分布偏移(面对训练数据分布外的输入时性能下降)会严重损害用户信任,而庞…...
【c++面向对象编程】第24篇:类型转换运算符:自定义隐式转换与explicit
目录 一、一个自然的想法 二、类型转换运算符的基本语法 写法 使用 三、隐式转换的风险 问题1:意外的不希望发生的转换 问题2:多个转换路径的歧义 问题3:与构造函数隐式转换叠加导致混乱 四、explicit:禁止隐式转换 语法…...
Maestro:基于YAML的声明式任务编排引擎,实现DevOps自动化工作流
1. 项目概述:从“指挥家”到“自动化交响乐”在软件开发和运维的世界里,我们常常扮演着“救火队员”的角色。一个微服务挂了,需要手动登录服务器查看日志;一个API接口响应慢了,得去翻监控图表找原因;新功能…...
Node.js代理池实战:proxy-agents库核心原理与高级应用
1. 项目概述与核心价值最近在折腾一些需要处理大量网络请求的自动化脚本,比如数据采集、API测试或者模拟用户操作,一个绕不开的痛点就是IP被封。单个IP频繁请求,对方服务器很容易就把你拉黑了。这时候,代理池就成了刚需。市面上成…...
