C++ UTF-8与GBK字符的转换 —基于Windows (MultiByteToWideChar WideCharToMultiByte)

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、UTF-8转GBK

首先写一个函数,定义如何转码

4.1.1、统计转换后的字节数 使用内置函数

现在格式是UTF8,即CP_UTF8.

int len = MultiByteToWideChar(CP_UTF8,	//转换的格式
		0,							//默认的转换方式
		data,						//输入的字节
		-1,							//输入的字符串大小 -1找\0结束  自己去算
		0,							//输出(不输出,统计转换后的字节数)
		0							//输出的空间大小
	);

4.1.2、用wtring存储数据,并为其分配大小

wstring udata; //用wstring存储的
udata.resize(len);//分配大小

 4.1.3、UTF-8转unicode。

将数据写进去,将数据强转为wchar_t类型,适用于windows和linux。

MultiByteToWideChar(CP_UTF8, 0, data, -1, (wchar_t*)udata.data(), len);

 4.1.4、unicode转GBK。

现在格式转成GBK,即CP_ACP。和UTF-8的参数数量不一样哦

len = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)udata.data(), -1, 0, 0,
		0, //失败替代默认字符
		0 //是否使用默认替代  0 false
	);

 4.1.5、配置字符大小,转成GBK

utf8.resize(len);
WideCharToMultiByte(CP_ACP, 0, (wchar_t*)udata.data(), -1, (char*)utf8.data(), len, 0, 0);

4.1.6、 UTF-8转GBK完整代码

string UTF8ToGBK(const char* data)
{
	string utf8 = "";
	//1、UTF8 先要转为unicode  windows utf16
	//1.1 统计转换后的字节数
	int len = MultiByteToWideChar(CP_UTF8,	//转换的格式
		0,							//默认的转换方式
		data,						//输入的字节
		-1,							//输入的字符串大小 -1找\0结束  自己去算
		0,							//输出(不输出,统计转换后的字节数)
		0							//输出的空间大小
	);
	if (len <= 0)
	{
		return utf8;
	}
	wstring udata; //用wstring存储的
	udata.resize(len);//分配大小
	//开始写进去
	MultiByteToWideChar(CP_UTF8, 0, data, -1, (wchar_t*)udata.data(), len);


	//2 unicode 转 GBK  
	len = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)udata.data(), -1, 0, 0,
		0, //失败替代默认字符
		0 //是否使用默认替代  0 false
	);
	if (len <= 0)
	{
		return utf8;
	}
	utf8.resize(len);
	WideCharToMultiByte(CP_ACP, 0, (wchar_t*)udata.data(), -1, (char*)utf8.data(), len, 0, 0);

	return utf8;
}

4.2、GBK转UTF-8

4.2.1、统计转换后的字节数

//1.1 统计转换后的字节数
	int len = MultiByteToWideChar(CP_ACP,	//转换的格式
		0,							//默认的转换方式
		data,						//输入的字节
		-1,							//输入的字符串大小 -1找\0结束  自己去算
		0,							//输出(不输出,统计转换后的字节数)
		0							//输出的空间大小
	);

4.2.2、用wstring存储数据,并为其分配大小 

wstring udata; //用wstring存储的
udata.resize(len);//分配大小

4.2.3、GBK转unicode 

//开始写进去
	MultiByteToWideChar(CP_ACP, 0, data, -1, (wchar_t*)udata.data(), len);

 4.2.4、unicode转UTF-8

//2 unicode 转 utf8
	len = WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)udata.data(), -1, 0, 0,
		0, //失败替代默认字符
		0 //是否使用默认替代  0 false
	);

 4.2.5、配置字符大小,转成UTF-8

GBK.resize(len);
WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)udata.data(), -1, (char*)GBK.data(), len, 0, 0);

4.2.6、GBK 转UTF-8 完整代码

string GBKToUTF8(const char* data)
{
	string GBK = "";
	//1、GBK转unicode
	//1.1 统计转换后的字节数
	int len = MultiByteToWideChar(CP_ACP,	//转换的格式
		0,							//默认的转换方式
		data,						//输入的字节
		-1,							//输入的字符串大小 -1找\0结束  自己去算
		0,							//输出(不输出,统计转换后的字节数)
		0							//输出的空间大小
	);
	if (len <= 0)
	{
		return GBK;
	}
	wstring udata; //用wstring存储的
	udata.resize(len);//分配大小
	//开始写进去
	MultiByteToWideChar(CP_ACP, 0, data, -1, (wchar_t*)udata.data(), len);


	//2 unicode 转 utf8
	len = WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)udata.data(), -1, 0, 0,
		0, //失败替代默认字符
		0 //是否使用默认替代  0 false
	);
	if (len <= 0)
	{
		return GBK;
	}
	GBK.resize(len);
	WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)udata.data(), -1, (char*)GBK.data(), len, 0, 0);

	return GBK;
}

5、测试

5.1、测试UTF-8转GBK

int main()
{
	//std::cout << "Hello World! 测试\n";

	//1、测试utf-8转GBK
	string in = u8"测试UTF-8转GBK";
	cout << "输入 UTF-8=" << in << endl;
	string gbk = UTF8ToGBK(in.c_str());
	cout << "输出GBK" << gbk << endl;
}

我们发现如果不进行转码的话,会出现乱码的情况,当通过转码之后,可以正常输出。

5.2、测试GBK转UTF-8

因为都是中文,在这里需要先GBK转UTF-8,再将UTF-8转换为GBK查看效果。

int main{	
    string utf8 = GBKToUTF8("测试GBK转UTF-8再转为GBK ");//出错的
	cout << "utf8:" << utf8 << endl;
	cout << UTF8ToGBK(utf8.c_str()) << endl;
}

6、完整可执行代码

//GBK转utf-8
#include<iostream>
#include<string>
using namespace std;
#include<Windows.h>


string UTF8ToGBK(const char* data)
{
	string utf8 = "";
	//1、UTF8 先要转为unicode  windows utf16
	//1.1 统计转换后的字节数
	int len = MultiByteToWideChar(CP_UTF8,	//转换的格式
		0,							//默认的转换方式
		data,						//输入的字节
		-1,							//输入的字符串大小 -1找\0结束  自己去算
		0,							//输出(不输出,统计转换后的字节数)
		0							//输出的空间大小
	);
	if (len <= 0)
	{
		return utf8;
	}
	wstring udata; //用wstring存储的
	udata.resize(len);//分配大小
	//开始写进去 
	MultiByteToWideChar(CP_UTF8, 0, data, -1, (wchar_t*)udata.data(), len);


	//2、 unicode 转 GBK 
	len = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)udata.data(), -1, 0, 0,
		0, //失败替代默认字符
		0 //是否使用默认替代  0 false
	);
	if (len <= 0)
	{
		return utf8;
	}
	utf8.resize(len);
	WideCharToMultiByte(CP_ACP, 0, (wchar_t*)udata.data(), -1, (char*)utf8.data(), len, 0, 0);

	return utf8;
}

string GBKToUTF8(const char* data)
{
	string GBK = "";
	//1、GBK转unicode
	//1.1 统计转换后的字节数
	int len = MultiByteToWideChar(CP_ACP,	//转换的格式
		0,							//默认的转换方式
		data,						//输入的字节
		-1,							//输入的字符串大小 -1找\0结束  自己去算
		0,							//输出(不输出,统计转换后的字节数)
		0							//输出的空间大小
	);
	if (len <= 0)
	{
		return GBK;
	}
	wstring udata; //用wstring存储的
	udata.resize(len);//分配大小
	//开始写进去
	MultiByteToWideChar(CP_ACP, 0, data, -1, (wchar_t*)udata.data(), len);


	//2 unicode 转 utf8  
	len = WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)udata.data(), -1, 0, 0,
		0, //失败替代默认字符
		0 //是否使用默认替代  0 false
	);
	if (len <= 0)
	{
		return GBK;
	}
	GBK.resize(len);
	WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)udata.data(), -1, (char*)GBK.data(), len, 0, 0);

	return GBK;
}

int main()
{
	//std::cout << "Hello World! 测试\n";

	//1、测试utf-8转GBK
	string in = u8"测试UTF-8转GBK";
	cout << "输入 UTF-8=" << in << endl;
	cout << endl;
	string gbk = UTF8ToGBK(in.c_str());
	cout << "输出GBK" << gbk << endl;
	cout << endl;

	//2、测试GBK转utf-8的转换
	string utf8 = GBKToUTF8("测试GBK转UTF-8再转为GBK ");//出错的
	cout << "utf8:" << utf8 << endl;
	cout << endl;
	cout << UTF8ToGBK(utf8.c_str()) << endl;
	cout << endl;
	system("pause");
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/296320.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

零日攻击:经典的传说!

零日攻击 1. 什么是零日漏洞2. 什么是零日市场3. 如何将零日漏洞转化为零日攻击4. 零日攻击的主要目标5. 典型零日攻击事件 1. 什么是零日漏洞 零日攻击是指利用零日漏洞对系统或软件应用发动的网络攻击。 零日漏洞也称零时差漏洞&#xff0c;通常是指还没有补丁的安全漏洞…

面试之线程状态

1.线程有哪些状态 1.1Java线程的六种状态 Java 线程六种状态 新建 当一个线程对象被创建&#xff0c;但还未调用 start 方法时处于新建状态 此时未与操作系统底层线程关联 可运行 调用了 start 方法&#xff0c;就会由新建进入可运行 此时与底层线程关联&#xff0c;由操作…

【AI视野·今日Sound 声学论文速览 第三十七期】Tue, 31 Oct 2023

AI视野今日CS.Sound 声学论文速览 Tue, 31 Oct 2023 Totally 11 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers DCHT: Deep Complex Hybrid Transformer for Speech Enhancement Authors Jialu Li, Junhui Li, Pu Wang, Youshan Zhang当前大多数基于深…

神经网络框架的基本设计

一、神经网络框架设计的基本流程 确定网络结构、激活函数、损失函数、优化算法&#xff0c;模型的训练与验证&#xff0c;模型的评估和优化&#xff0c;模型的部署。 二、网络结构与激活函数 1、网络架构 这里我们使用的是多层感知机模型MLP(multilayer prrceptron)&#x…

代码随想录 1143. 最长公共子序列

题目 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些字符&#xff08;也…

MongoDB 启动时:服务名无效

1.问题场景 电脑睡眠后&#xff0c;再连接服务发现无法连接&#xff0c;启动服务报&#xff1a;服务名无效。 2.打开服务管理&#xff1a; 发现服务中没有MongoDB的服务 3.解决 &#xff08;1&#xff09;先找打MongoDB安装路径&#xff0c;把data文件夹下所有文件删除 &a…

Vue中使用Element UI的Table组件实现嵌套表格(最简单示例)

以下是一个简单的示例代码&#xff0c;演示如何在Vue中使用Element UI的Table组件实现嵌套表格&#xff1a; html <template><div><el-table :data"tableData" style"width: 100%"><el-table-column prop"name" label&quo…

Centos服务器安装Certbot以webroot的方式定时申请SSL免费证书

最近发现原先免费一年的SSL证书都改为3个月的有效期了&#xff0c;原先一年操作一次还能接受&#xff0c;现在3个月就要手动续期整的太慢烦了&#xff0c;还是让程序自动给处理下吧&#xff0c; 安装 Certbot yum install epel-release -y yum install certbot -yEPEL是由 Fe…

云计算历年题整理

第一大题 第一大题计算 给出计算连接到EC2节点的EBS的高可用性(HA)的数学公式&#xff0c;如场景中所述&#xff1b;计算EC2节点上的EBS的高可用性(HA)&#xff1b;场景中80%的AWS EC2节点用于并行处理&#xff0c;总共有100个虚拟中央处理单元(vCPUs)用于处理数据&#xff0…

蟹目标检测数据集VOC格式400张

蟹&#xff0c;一种独特的海洋生物&#xff0c;以其强壮的身体和独特的生活习性而闻名。 蟹的身体宽厚&#xff0c;有一对锐利的大钳子&#xff0c;这使得它们在寻找食物和保护自己时非常有力。蟹的外观颜色多样&#xff0c;有绿色、蓝色、棕色和红色等&#xff0c;这使得它们在…

法一(auto-py-to-exe):Pyinstaller将yolov5的detect.py封装成detect.exe

pip install pyinstaller # 安装最新版本的pyinstaller指令# 在dist目录下只生成一个较大xxx.exe文件&#xff0c;所有依赖库全打包到exe中&#xff0c;打包后的exe可单独使用 pyinstaller -F xxx.py # 在dist目录下生成较小的exe文件&#xff0c;其他依赖库全都在dist文件夹下…

[C#]利用opencvsharp实现深度学习caffe模型人脸检测

【官方框架地址】 https://github.com/opencv/opencv/blob/master/samples/dnn/face_detector/deploy.prototxt 采用的是官方caffe模型res10_300x300_ssd_iter_140000.caffemodel进行人脸检测 【算法原理】 使用caffe-ssd目标检测框架训练的caffe模型进行深度学习模型检测 …

【ARMv8架构系统安装PySide2】

ARMv8架构系统安装PySide2 Step1. 下载Qt资源包Step2. 配置和安装Qt5Step3. 检查Qt-5.15.2安装情况Step4. 安装PySide2所需的依赖库Step5. 下载和配置PySide2Step6. 检验PySide2是否安装成功 Step1. 下载Qt资源包 if you need the whole Qt5 (~900MB): wget http://master.qt…

全新盲盒商城源码 /潮乎盲盒源码 /搭建教程/后端采用Laravel框架开发

源码介绍&#xff1a; 全新盲盒商城源码、潮乎盲盒源码&#xff0c;它附有搭建教程&#xff0c;后端采用Laravel框架开发。 采用后端Laravel框架进行开发&#xff0c;前端开发框架则使用了uniappvue。在环境配置方面&#xff0c;我们建议使用php7.4 mysql5.6 nginx1.22 re…

用友U8 Cloud smartweb2.RPC.d XML外部实体注入漏洞

产品介绍 用友U8cloud是用友推出的新一代云ERP&#xff0c;主要聚焦成长型、创新型、集团型企业&#xff0c;提供企业级云ERP整体解决方案。它包含ERP的各项应用&#xff0c;包括iUAP、财务会计、iUFO cloud、供应链与质量管理、人力资源、生产制造、管理会计、资产管理&#…

MATLAB中xcorr函数用法

目录 语法 说明 示例 两个向量的互相关 向量的自相关 归一化的互相关 xcorr函数的功能是返回互相关关系。 语法 r xcorr(x,y) r xcorr(x) r xcorr(___,maxlag) r xcorr(___,scaleopt) [r,lags] xcorr(___) 说明 r xcorr(x,y) 返回两个离散时间序列的互相关。互相…

基于R语言(SEM)结构方程模型教程

详情点击链接&#xff1a;基于R语言&#xff08;SEM&#xff09;结构方程模型教程 01、R/Rstudio (2)R语言基本操作&#xff0c;包括向量、矩阵、数据框及数据列表等生成和数据提取等 (3)R语言数据文件读取、整理&#xff08;清洗&#xff09;、结果存储等&#xff08;含tidve…

助力实体店数字化升级,VR智慧门店打造线上逛店体验

近年来&#xff0c;传统实体店业绩增长过于缓慢&#xff0c;实体门店的销售疲态十分明显&#xff0c;甚至于部分城市已经出现大量线下实体店开始关门的现象&#xff0c;因此顺应实体零售数字化升级趋势已经刻不容缓。越来越多的实体门店开始意识到这个问题&#xff0c;并逐步开…

window服务器thinkphp队列监听服务

经常使用linux的同学们应该对使用宝塔来做队列监听一定非常熟悉&#xff0c;但对于windows系统下&#xff0c;如何去做队列的监听&#xff1f;是一个很麻烦的事情。 本文将通过windows系统的服务来实现队列的监听。 对于thinkphp6 queue如何使用&#xff0c;不再赘述。其它系…

算法29:不同路径问题(力扣62和63题)--针对算法28进行扩展

题目&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff0…
最新文章