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 小程序…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

【若依】框架项目部署笔记
参考【SpringBoot】【Vue】项目部署_no main manifest attribute, in springboot-0.0.1-sn-CSDN博客 多一个redis安装 准备工作: 压缩包下载:http://download.redis.io/releases 1. 上传压缩包,并进入压缩包所在目录,解压到目标…...
boost::filesystem::path文件路径使用详解和示例
boost::filesystem::path 是 Boost 库中用于跨平台操作文件路径的类,封装了路径的拼接、分割、提取、判断等常用功能。下面是对它的使用详解,包括常用接口与完整示例。 1. 引入头文件与命名空间 #include <boost/filesystem.hpp> namespace fs b…...

工厂方法模式和抽象工厂方法模式的battle
1.案例直接上手 在这个案例里面,我们会实现这个普通的工厂方法,并且对比这个普通工厂方法和我们直接创建对象的差别在哪里,为什么需要一个工厂: 下面的这个是我们的这个案例里面涉及到的接口和对应的实现类: 两个发…...
当下AI智能硬件方案浅谈
背景: 现在大模型出来以后,打破了常规的机械式的对话,人机对话变得更聪明一点。 对话用到的技术主要是实时音视频,简称为RTC。下游硬件厂商一般都不会去自己开发音视频技术,开发自己的大模型。商用方案多见为字节、百…...