Windows平台Qt6中UTF8与GBK文本编码互相转换、理解文本编码本质

2023-09-20 21:22:05

快速答案

  1. UTF8转GBK
QString utf8_str="中UTF文";
std::string gbk_str(utf8_str.toLocal8Bit().data());
  1. GBK转UTF8
std::string gbk_str_given_by_somewhere="中GBK文";
QString utf8_str=QString::fromLocal8Bit(gbk_str_given_by_somewhere.data());

正文

当你在搜寻【Windows平台Qt6中UTF8与GBK文本编码互相转换】的答案时,你实际上遇到的是【Windows平台Qt6与纯C++的字符串编码转换问题】。
Qt6框架内部默认使用UTF编码,Windows文件路径默认GBK(可以通过[控制面板]-[区域]-[管理]-[更改系统区域设置]-[勾选使用Unicode UTF-8]进行更改,但是截止到当前2023年正如勾选框所说这是Beta版本功能,会导致大量使用硬编码GBK的软件无法运行)。因此Qt本身不存在UTF8与GBK转换问题,Qt应用层输入输出都是UTF8,而纯C++本身不会进行编码转换,Windows系统调用只支持GBK,Windows平台下Qt与纯C++的交互会遇到转换问题,例如打印字符串、打开文件路径等。

1. 文本编码原理

  • 什么是文本编码
    计算机中,所有信息都以二进制形式储存在内存中,文本同样是一堆字节。
    直接抛给让两个人一串字节,两个人可能会理解出不同的文本信息,比如一串字节{0xd6,0xd0,0xce,0xc0},你会认为代表什么文本呢?如果一个人只懂ASCII编码,他查了ASCII表后会认为是[Ö,Ð,Î,À];如果一个人只懂GBK编码,他查了GBK表后会认为是[中,文]。就是因为有这些表,就像二战时的电报一样,一串二进制可以被不同的解密方式解密出不同的语义信息。
    人类能看到的文本被加密(编码)后成为了一串二进制,一串二进制被解密(解码)后成为了人类看到的文本。因此小明用A规则去加密文本得到的二进制,再用B规则去解密得到的文本,必然不是小明当初看到的文本。对应地,文本用UTF编码得到的二进制,再用GBK解码得到的文本基本上是乱码,反之亦然。
  • 计算机如何编码和解码
    编码不用多说,按照用户指定的表将用户输入的文本转换为二进制即可。解码就要麻烦一点了,程序并不知道接收到的一串二进制是什么编码,两种方法,一是硬解码,就像Qt,不管三七二十一直接按照UTF格式解;二是智能判断这个二进制是什么编码,例如vscode里就有这个功能,但是可能有误判问题,所以需要人为确认。

2. 默认下Qt6有意义的操作只支持UTF编码输入

  • 何为有意义?例如
    – QString经常被拿来当作文件路径,QString变量创建时强制解析为UTF;
    – QFile的文件路径用来打开文件,强制解析为UTF;
    – qDebug()要与命令行交互,输入的字符串强制解析为UTF,这就是为什么在只支持GBK的命令终端用qDebug打印GBK文本会出现乱码;
    – QFile写入文件的字符串内容不会被Qt转码,因为文件内容字符串本身是没有意义的,只需要将原来的内容不用转码而直接搬运写入即可。
  • 何为默认?例如以下:
std::string std_str="中文";
QString s1=QString::fromStdString(std_str);
QString s2="中文";
qDebug()<<s1<<s2;

s1和s2的右侧内容均被默认按照UTF解码保存,见下图官方文档所述,用了fromUtf8()。代码中,如果你的cpp文件是GBK编码的,那输出乱码,因为GBK编码的字符串却被Qt默认按照UTF解码了;如果你的cpp文件是UTF编码的,那输出正常的中文,因为UTF编码的字符串被Qt默认按照UTF解码,对的上。等号运算符fromStdString

Qt支持程序员指定的非默认的编码转换,例如以下:

std::string std_str="中文";
QString s=QString::fromLocal8Bit(std_str.data());
qDebug()<<s;

代码做了这些操作:将文本原始字节数组按照Local(本地计算机,Windows默认GBK)的格式转码成UTF,QString再按照UTF格式进行解码,符合Qt的UTF入口要求,输出正常的中文。

3. Qt输出是GBK还是UTF?

Qt在开放给程序员的api层面,是UTF,例如QStringtoStdString()函数输出的就是UTF编码的字符串,官方文档描述见下图,自动用了toUtf8();Qt内部直接与操作系统调用的部分,会自动toLocal操作,例如qDebug(),当它的输入为UTF编码的中文时,可以正确打印中文到只支持GBK的命令终端,这是因为Qt直接调用Windows系统函数时,会根据自动toLocal。
toStdString

4.GBK与UTF8互转的几种方法

  • icu
    跨平台编码转换库,Qt底层有用到这个库。
  • iconv
    Linux平台编码转换库。
  • windows.h
    windows平台专用,使用函数MultiByteToWideChar和WideCharToMultiByte。
  • std::codecvt
    C++标准库实现的编码转换,已经被标记为弃用,不建议使用。
  • Qt toLocal8Bit和fromLocal8Bit
    Qt框架配合自己的数据结构QString等,使用Qt时首选。
  • Qt QStringConvert
    内部调用与toLocal8Bit和fromLocal8Bit一样。
更多推荐

HTTP、HTTPS协议详解

文章目录HTTP是什么报文结构请求头部响应头部工作原理用户点击一个URL链接后,浏览器和web服务器会执行什么http的版本持久连接和非持久连接无状态与有状态Cookie和Sessionhttp方法:get和post的区别状态码HTTPS是什么ssl如何搞到证书nginx中的部署加密CA数字证书hash算法对称加密非对

【雕爷学编程】MicroPython动手做(25)——语音合成与语音识别2

知识点:什么是掌控板?掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED显示屏、RGB灯、加速度计、麦克风、光线传感器、蜂鸣器、按键开关、触摸开关、金手指外部拓展接口,

【PostgreSQL】系列之 一 用户创建和授权(三)

🍁博主"开着拖拉机回家"带您GotoNewWorld.✨🍁🦄个人主页——🎐开着拖拉机回家_Linux,Java基础学习,大数据运维-CSDN博客🎐✨🍁🪁🍁希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批评指正!🍁🐥目录🍁博主"开着拖拉机回家"带您GotoNewWorld.✨🍁一、Postgre

掌握无人机遥感数据预处理的全链条理论与实践流程、典型农林植被性状的估算理论与实践方法、利用MATLAB进行编程实践(脚本与GUI开发)以及期刊论文插图制作等

目录专题一认识主被动无人机遥感数据专题二预处理无人机遥感数据专题三定量估算农林植被关键性状专题四期刊论文插图精细制作与Appdesigner应用开发近地面无人机植被定量遥感与生理参数反演更多推荐遥感技术作为一种空间大数据手段,能够从多时、多维、多地等角度,获取大量的农情数据。数据具有面状、实时、非接触、无伤检测等显著优

【Spring Boot】单元测试

单元测试单元测试在日常项目开发中必不可少,SpringBoot提供了完善的单元测试框架和工具用于测试开发的应用。接下来介绍SpringBoot为单元测试提供了哪些支持,以及如何在SpringBoot项目中进行单元测试。1.SpringBoot集成单元测试单元测试主要用于测试单个代码组件,以确保代码按预期方式工作。目前流

入门Echarts数据可视化:从基础到实践

目录引言数据可视化的重要性Echarts资源与拓展Echarts简介及开发准备什么是EchartsEcharts的特点与优势安装Echarts引入Echarts库第一个图表使用Echarts绘制一个简单的柱状图数据准备与图表配置数据格式要求图表标题与标签设置实践与性能优化提升图表渲染性能的技巧响应式设计与移动端适配引言

数据分析实战│价格预测挑战【文末赠书】

文本分析是指对文本信息的表示及特征项的选取,商品文本的描述能够反映特定立场、观点、价值和利益。考虑到网上海量的商品数量,对产品的定价难度很大,因此可以使用商品描述帮助商户定价。比如,服装具有较强的季节性价格趋势,受品牌影响很大,而电子产品则根据产品规格波动。因此,根据商品提供的文本信息进行合理地定价,能够有效地帮助商家

第32节——useReducer——了解

一、概念useReducer是在reactV16.8推出的钩子函数,从用法层面来说是可以代替useState。众所周知,useState常用在单个组件中进行状态管理,但是遇到状态全局管理的时候,useState显然不能满足我们的需求,这个时候大多数的做法是利用第三方的状态管理工具,像redux,Recoil或者Mobx

IPO解读丨Arm破解市场质疑的答案,仍在AI中?

时隔7年,移动设备芯片领域霸主Arm重回二级市场。IPO进程的推进,让这家全球芯片行业的基石公司,不得不面对来自市场的全方位的密集审视。而从股价来看,投资者对于Arm的态度始终处于摇摆中,从上市首日股价大涨25%,到截至发稿前的三个交易日股价累计下跌12.5%,可以看出,Arm在二级市场面临一定质疑。但不可否认Arm在

ChatGPT技术原理

Task03ChatGPT技术原理目录阶段一:有监督微调Supervisedfine-tuning(SFT)阶段二:训练回报模型(RewardModel,RM)阶段三:使用强化学习微调SFT模型ChatGPT是由GPT-3迭代来的,原有的GPT-3可能难以从文本中学会一些更高层次的表示,这就导致了GPT-3这样的语言模

指针和数组笔试题深度解析

学习之前我们将运用到sizeof和strlen函数sizeof和strlen函数认识和区别:1.strlen是一个库函数使用时需要引用#include<string.h>这个头文件,而sizeof是一个运算符号;2.strlen计算的是'\0'之前的字符个数,sizefo计算的是所占空间内存的大小,单位是字节;3.st

热文推荐