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 转 utf8len = 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 转 utf8len = 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转GBKstring 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转GBKstring 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.mzph.cn/news/600716.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

word2019保存后的图片变模糊了怎么办?Word 2019 默认保存后压缩变模糊的问题,解决方案

Word 2019 默认保存后压缩变模糊的问题&#xff0c;解决方案 1&#xff0c;新建word 文件&#xff0c;插入一张原始图片&#xff0c;1080*1920&#xff0c;如下图&#xff1a; 2&#xff0c;保存时&#xff0c;word 2019默认选项&#xff0c;导致word 保存后&#xff0c;图片…

CTFshow web入门web127-php特性30

开启环境: extract() 函数从数组中将变量导入到当前的符号表&#xff0c;使用数组键名作为变量名&#xff0c;使用数组键值作为变量值 举例就是?a2&#xff0c;就会变成$a2&#xff0c;这里ctf_show有个_需要构造&#xff0c;前面说过php中变量名只有数字字母下划线&#xff…

<HarmonyOS主题课>1~3课后习题汇总

&#xff1c;HarmonyOS第一课&#xff1e;1~10课后习题汇总 1使用DevEco Studio高效开发 单选题 用哪一种装饰器修饰的组件可作为页面入口组件&#xff1f;&#xff08;B&#xff09; A. ComponentB. EntryC. PreviewD. Builder ArkTS Stage模型支持API Version 9&#xf…

uniapp 日历组件

我们的需求是显示当前月和下个月的排班表 引入 uniapp 日历组件 uni-calendar 做法有两种&#xff0c;一种是直接去修改组件&#xff0c;还有就是文档中提供的 selected 方法 修改组件的就不写了 <uni-calendar :lunar"true" :selected"selected" :in…

【demoSURF】室内定位(图像匹配)基础代码实现,包含所有可以出现问题的解法

代码如下 import numpy as np import cv2 from matplotlib import pyplot as plt plt.rcParams[font.sans-serif] [SimHei] # 用来正常显示中文标签 plt.rcParams[axes.unicode_minus] False # 用来正常显示负号img1 cv2.imread("D:/data/North/0007.JPG",0) i…

【C语言】自己代码实现字符串相关的常用API

目录 1、实现get(char *)&#xff1b;从键盘获取字符串2、实现put&#xff08;char *&#xff09;&#xff1b;输出字符串3、实现strlen&#xff08;char *&#xff09;&#xff1b;求字符串长度4、实现strcpy&#xff08;char *&#xff0c;char *&#xff09;&#xff1b;拷贝…

C#,入门教程(11)——枚举(Enum)的基础知识和高级应用

上一篇&#xff1a; C#&#xff0c;入门教程(10)——常量、变量与命名规则的基础知识https://blog.csdn.net/beijinghorn/article/details/123913570 不会枚举&#xff0c;就不会编程&#xff01; 枚举 一个有组织的常量系列 比如&#xff1a;一个星期每一天的名字&#xf…

使用HttpSession和过滤器实现一个简单的用户登录认证的功能

这篇文章分享一下怎么通过session结合过滤器来实现控制登录访问的功能&#xff0c;涉及的代码非常简单&#xff0c;通过session保存用户登录的信息&#xff0c;如果没有用户登录的话&#xff0c;会在过滤器中处理&#xff0c;重定向回登录页面。 创建一个springboot项目&#…

Visual Studio 2017 + opencv4.6 + contribute + Cmake(Aruco配置版本)指南

之前配置过一次这个&#xff0c;想起这玩意就难受&#xff0c;贼难配置。由于要用到里面的一个库&#xff0c;不得已再进行配置。看网上的博客是真的难受&#xff0c;这写一块&#xff0c;那里写一块&#xff0c;乱七八糟&#xff0c;配置一顿发现写的都是错的&#xff0c;还得…

Materail Design 进阶(十一)——MaterialButton使用

距离上次写Material组件的文章已经过去了好多年&#x1f604;&#xff0c;最近在写Flutter又接触到了Material&#xff0c;已经升级了许多&#xff0c;这次就用新的组件来试试吧&#xff5e; Button组件大家都非常熟悉了&#xff0c;如果画一个带圆角&#xff0c;边框的按钮&a…

FFmpeg读取Assets资源文件

在Android开发中我们经常把原生资源文件放在assets目录下以供需要时读取&#xff0c;通过API提供的resources.assets.open(filename)/openFd(filenam)方法可以非常方便获得InputStream或FileDescriptor&#xff08;文件标识符&#xff09;&#xff0c;但是在使用FFmpeg读取Asse…

JavaScript系列——同步与异步

文章目录 概要同步代码&#xff1a;异步代码 JavaScript运行机制运行时概念栈&#xff08;stack&#xff09;堆队列消息的添加 异步场景网络请求 异步编程优化小结 概要 异步&#xff0c;按照字面理解&#xff0c;指的是两个或者两个以上的对象或事件不同时存在或者发生&#…

透明OLED屏的稳定性:从技术角度及应用案例解析

在显示技术日新月异的今天&#xff0c;透明OLED屏以其独特的透明特性和出色的显示效果&#xff0c;吸引了众多关注。然而&#xff0c;对于这种新型技术的稳定性&#xff0c;人们难免会有所疑虑。作为一名专注于OLED技术研发的工程师&#xff0c;尼伽小编将从专业角度出发&#…

十种编程语言的对比分析

在当今的软件开发领域&#xff0c;编程语言扮演着至关重要的角色。不同的编程语言各有其特点和适用场景&#xff0c;选择合适的编程语言能够提高开发效率和软件质量。本文将对十种常见的编程语言进行对比分析&#xff0c;帮助读者了解它们的优缺点和适用场景。 一、Python Pyt…

云化XR技术于农业领域中的表现

随着科技的不断发展和应用的深入&#xff0c;农业领域也在逐渐引入新技术来优化生产效率和成本、改进管理和监控等。云化XR&#xff08;CloudXR&#xff09;作为一种融合了云计算、虚拟现实&#xff08;VR&#xff09;和增强现实&#xff08;AR&#xff09;等技术的解决方案&am…

生信技能33 - gnomAD数据库hg19/hg38 VCF文件批量下载脚本

gnomAD数据库下载地址 gnomAD downloads gnomAD v2.1.1数据集包含来自125,748个外显子组和15,708个全基因组的数据,所有这些数据都映射到GRCh 37/hg 19和GRCh 38/hg 38 两个版本的参考序列。 gnomAD数据库hg19与hg39 VCF文件批量下载脚本 download.sh # 获取当前目录路径…

C++-异常处理

1、概念 异常时程序在执行期间产生的问题。C异常是指在程序运行时发生的特殊情况。比如string::at函数下标越界等。 异常提供了一种转移程序控制权的方式。 一旦程序出现异常没有经过处理&#xff0c;就会造成程序运行崩溃。 处理异常的方式有&#xff1a;抛出异常&#xff08;…

Python基础(十九、文件操作写入与追加)

文章目录 一、文件的写入&#xff08;使用 "w" 模式&#xff09;二、文件的追加&#xff08;使用 "a" 模式&#xff09;三、文件备份案例接之前的答案 在 Python 中&#xff0c;open() 是一个内置函数&#xff0c;用于打开文件并返回文件对象。它是处理文件…

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

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

cad快速看图软件免费版(手机在线cad快速看图)

cad快速看图软件免费版(手机在线cad快速看图) 很多机械设计师日常工作过程中涉及到多种格式的cad图纸&#xff0c;cad图纸大多都需要cad设计软件才能打开&#xff0c;然而很多小伙伴并没有下载相应的cad设计软件&#xff0c;这种情况下如何进行cad快速看图呢&#xff1f; 今天…