当前位置: 首页 > news >正文

Qt 4.8.7 + MSVC 中文乱码问题深入分析

此问题很常见,然而网上关于此问题的分析大多不够深刻,甚至有错误;加之Qt5又更改了一些编码策略,而很多文章并未提及版本问题,或是就算提了,读者也不重视。这些因素很容易让读者产生误导。今日我彻底研究透了这个问题,在此记录。

环境:Qt 4.8.7, Qt Creator 4.2.2, MSVC 2015

Qt 4.8.7 + MSVC 的中文乱码问题,实际上有两层原因。

第一层:MSVC 不识别无 BOM 的 UTF-8

Qt Creator 默认源代码文件编码是无BOM的UTF-8,而MSVC编译器会误认为这是本地多字节字符集(MBCS)编码(对于简中地区,即GBK,代码页936)。

解决方法1(推荐):Qt Creator选项—文本编辑器—文件编码—UTF8 BOM——如果编码是UTF8则添加—确定。
解决方法2:Qt Creator选项—文本编辑器—文件编码—默认编码—GBK—确定。

注意:修改以上两种方法提及的设置后,Qt Creator并不会自动修改已保存的文件的编码或BOM。我们需要修改一下含中文的文件,重新Ctrl+S保存,这样才能将这些设置应用于这些文件。

第二层:QString 构造函数默认假定的文本编码不正确

我们代码中的字符串,特别是用于测试这个乱码问题的字符串,一般都是C样式的,即用一对双引号包围的const char []类型字符串字面量,如 "Hello World" 。然而 Qt 里很多函数的参数要求的字符串类型都是 QString,我们填入这种C样式字符串时就会有个隐式转换,转为QString类型,其实也就是QString这个构造函数在帮我们转换:

explicit QString::QString(const char* ch)

 然而const char*类型只表明了这个字符串是多字节字符集,却没指明是哪一种,他可能是GBK, UTF-8等等,甚至可能是跟咱这边八竿子打不着的西欧语言字符集Latin-1(ISO-8859-1)。不加声明的话,MSVC默认我们的字符串字面量是本地多字节字符集(MBCS),即GBK编码,如下图左侧“标题title”文本所示情况。而如果在这种C样式字符串的引号前加上“u8”二字,则MSVC就会认为此字符串是UTF-8编码,如下图右侧“文本text”文本所示情况。

 MSVC在我们有或没有声明的情况下判断出了此字符串的编码后,对此字符串进行编码,也就是将它们转换为二进制的字节数据,传给QString的构造函数。

注意:
①即使在上一层问题的解决中,我们选择了保留UTF-8,加上BOM供MSVC识别,以上所述MSVC对C样式字符串的编码的解析方式仍然成立。他不会因为你的源码文件是UTF-8编码,就将其中的这种字符串优先视为UTF-8。所以上一层问题你选择了哪种解决方法对这一层问题是没有影响的。
②“u8”标记只是给MSVC编译器的提示,MSVC处理后,不管是加了u8还是没加,一律变成const char[]这样的字节数组。也就是说,有没有u8,QString的构造函数是不知道的,看不见的。他只知道传进来了一个const char* 类型。

传给QString的构造函数后,QString要解码这些二进制数据,也就是将它们映射到可显示(我们能看懂)的字符上。由于这些数据不能体现编码,他就要猜。咱当然希望他猜是GBK啦,但是事与愿违,Qt库毕竟不是中国人写的。他默认猜成西欧语言字符集Latin-1(如图)!这就会导致我们在代码里写了些汉字,却显示出一堆拉丁字母甚至音标。这也是为何在没有QString参与的情况下只解决第一层问题就好了,例如控制台窗口的std::cout,而在需要把const char*转换成QString时就又会出问题。

那么解决思路已经很明显了。要么修改它的设置,让他猜成GBK(或UTF-8),要么明明白白的告诉他我们的字符串是啥编码(使用 QString::fromXXX 函数)。

解决方法1(推荐):在 QApplication 对象创建前将“C样式字符串的编码(CodecForCStrings)”设为UTF-8,并在每个含中文的字符串字面量的前导引号前加上u8二字(如QString str(u8"这是中文");)。设置“C样式字符串的编码”的方法是:在程序的入口点(main函数)中最开始的位置加上图中这句代码(别忘了加头文件):

QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));

解决方法2: 跟方法1一样修改“C样式字符串的编码”,但设为本地多字节字符集(MBCS,一般是GBK),代码中的字符串字面量不加“u8”(如QString str("这是中文");)。具体方法和上条类似,不再赘述,但main函数中加的那句代码改为:

QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());

解决方法3: 在每个字符串字面量的前导引号前加上u8,并用 QString::fromUtf8() 包裹,如图:

解决方法4:字符串字面量的前导引号前不加u8,并用 QString::fromLocal8Bit() 包裹,如图:


依次解决以上两层问题后,中文就不再乱码了。再次强调,本文只针对 Qt 4.8.7 + MSVC2015 环境提供问题原理和解决方案,Qt5就不一样了,说不定微软也会在未来的MSVC中添加对无BOM的UTF-8文件的识别。那时,问题的解决将简单很多。

szx0427 作于 2024/07/17

相关文章:

Qt 4.8.7 + MSVC 中文乱码问题深入分析

此问题很常见,然而网上关于此问题的分析大多不够深刻,甚至有错误;加之Qt5又更改了一些编码策略,而很多文章并未提及版本问题,或是就算提了,读者也不重视。这些因素很容易让读者产生误导。今日我彻底研究透了…...

IDEA的常见代码模板的使用

《IDEA破解、配置、使用技巧与实战教程》系列文章目录 第一章 IDEA破解与HelloWorld的实战编写 第二章 IDEA的详细设置 第三章 IDEA的工程与模块管理 第四章 IDEA的常见代码模板的使用 第五章 IDEA中常用的快捷键 第六章 IDEA的断点调试(Debug) 第七章 …...

arcgis怎么选取某个指定区域地方的数据,比如从全国乡镇数据选取长沙市乡镇数据

一共5个步骤,没一句废话,耐心看完。看完你就会在任何软件选取指定范围的数据了。 一、如图,先将数据加载到arcgis里面,我们要选取里面长沙市的范围数据。 二、选取长沙市的语句 “市” like ‘长沙%’ 切记,切记&…...

二、链表(1)

203.移除链表元素 创建一个虚拟哨兵头节点,就不用考虑原本头结点要不要删除 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def remove…...

KAFKA搭建教程

KAFKA搭建教程 期待您的关注 KAFKA学习笔记 帮助更多人 目录 KAFKA搭建教程 1.下载Kafka并解压 2.添加环境变量 3.修改 server.properties 文件 4.将kafka复制到其它节点 5.修改node1、node2节点的broker.id 6.将master的环境变量同步到node1、 node2 7.启动zookeeper…...

Linux网络——套接字与UdpServer

目录 一、socket 编程接口 1.1 sockaddr 结构 1.2 socket 常见API 二、封装 InetAddr 三、网络字节序 四、封装通用 UdpServer 服务端 4.1 整体框架 4.2 类的初始化 4.2.1 socket 4.2.2 bind 4.2.3 创建流式套接字 4.2.4 填充结构体 4.3 服务器的运行 4.3.1 rec…...

SpringBoot源码深度解析

今天,聊聊SpringBoot的源码,本博客聊的版本为v2.0.3.RELEASE。目前SpringBoot的最新版为v3.3.2,可能目前有些公司使用的SpringBoot版本高于我这个版本。但是没关系,因为版本越新,新增的功能越多,反而对Spri…...

【Qt】常用控件

文章目录 QWidgetenabledgeometrywindow framewindowTitlewindowIconqrc资源管理windowOpacitycursorfonttoolTipfocusPolicystyleSheet 按钮类PushButtonRadioButtonCheckBoxSignals 显示类LabelLCDNumberProgressBarCalendar 输入类LineEditTextEditComboBoxSpinBoxDateTimeE…...

electron 主进程和渲染进程通信

在Electron中,主进程(main process)和渲染进程(renderer process)之间的通信是非常重要的,因为Electron应用通常会将用户界面(由Web技术如HTML, CSS, 和JavaScript构建)和原生功能(如系统对话框、文件I/O等)分开处理。主进程管理应用的生命周期和创建渲染进程,而渲染…...

【ARM】MDK-解决CMSIS_DAP.DLL missing报错

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 记录解决CMSIS_DAP.DLL missing的报错情况,对应相关报错信息,供后续客户参考,快速解决客户问题。 2、 问题场景 客户进行硬件调试时,发现Target设置内有CMSIS_DAP.DL…...

CSS 的环境变量函数env()

在CSS中,env() 函数并不是传统意义上的“环境变量”函数,如你在编程语言中可能遇到的那样。相反,env() 是CSS中的一个函数,它用于访问由宿主环境(如浏览器)提供给CSS的自定义属性(也称为环境变量…...

数学建模--国赛备赛---TOPSIS算法

目录 1.准备部分 1.1提交材料 1.2MD5码相关要求 2.TOPSIS算法 2.1算法概述 2.2基本概念 2.3算法核心思想 2.4拓展思考 3.适用赛题 3.1适用赛题说明 3.2适用赛题举例 4.赛题分析 4.1指标的分类 4.2数据预处理 4.2.1区间型属性的变换 4.2.2向量规范化 4.3数据加…...

均值滤波算法及实现

均值滤波器的使用场景: 均值滤波器使用于处理一些如上述蓝色线的高斯噪声场景 红色曲线是经过均值滤波处理后的数据。主要因为均值滤波设置数据缓冲区(也即延时周期),使得测量值经过缓冲不会出现特别大的变化。 黄色曲线为高斯噪声…...

【Apache Doris】周FAQ集锦:第 16 期

【Apache Doris】周FAQ集锦:第 16 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目! 在这个栏目中,每周将筛选社区反馈的热门问题和话题,重点回答并进行深入探讨。旨在为广大用户…...

单例模式_Golang

目录 一、单例模式 1.1 基本概念 1.2 使用场景 二、Golang实现 2.1 懒汉模式(Lazy Loading) 一、单例模式 1.1 基本概念 一个类只能生成一个实例,且该类能自行创建这个实例的一种模式,这个定义个人感觉可以拆的通俗一些,在项目的生命周…...

代码随想录 day 18 二叉树

第六章 二叉树part06 详细布置 530.二叉搜索树的最小绝对差 需要领悟一下二叉树遍历上双指针操作,优先掌握递归 题目链接/文章讲解:https://programmercarl.com/0530.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E6%9C%80%E5%B0%8F%E7%B…...

降雨量预测 | Matlab基于ARIMA-RBF降雨量预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 降雨量预测 | Matlab基于ARIMA-RBF降雨量预测 注:程序和数据放在一个文件夹。 程序语言为matlab,程序可出预测效果图,指标图; 代码特点:参数化编程、参数可方便更改、代…...

包含示例和模板的流程文档指南

当您的业务扩展时,您会得到越来越多的移动部件,并且需要有人来跟踪复杂性。人员和任务需要以尽可能最高效的方式进行组织,并且您必须找到某种方法让员工知道如何执行有效完成工作所需的流程。 为了使流程可重复,需要对其进行记录…...

51单片机嵌入式开发:15、STC89C52RC操作蜂鸣器实现一个music音乐播放器的音乐盒

STC89C52RC操作蜂鸣器实现一个music音乐播放器的音乐盒 1 概述2 蜂鸣器操作方法3 蜂鸣器发出音声4 硬件电路5 软件实现6 整体工程:7 总结 1 概述 要实现一个基于STC89C52RC单片机的音乐盒,可以按照以下步骤进行: (1)硬…...

B树(B-Tree)数据结构

1. 什么是B树? B树(B-Tree)是一种多路搜索树,用于存储和检索大量数据。它是自适应的,适用于各种存储设备和各种数据量。B树的特点是高效的搜索、插入和删除操作,且可以在各种情况下保持树的平衡。 2. B树…...

从NDVI到地表温度:用ENVI Band Math一次性搞定植被与热环境分析

ENVI波段运算实战:NDVI与地表温度的高效批量处理技巧 遥感影像分析中,植被指数和地表温度是最基础却又最关键的指标。传统操作流程往往需要反复切换不同工具模块,既耗时又容易出错。而ENVI的Band Math功能就像一把瑞士军刀,能将这…...

复现顶刊《金融研究》- 金融周期如何影响房地产价格?(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

别再只用Wireshark了!用Cain Abel在Windows上5分钟复现ARP欺骗攻击(附实战截图)

从Wireshark到Cain & Abel:用经典工具5分钟掌握ARP欺骗核心原理 如果你已经能用Wireshark分析网络流量,却对ARP欺骗的原理一知半解,那么这款诞生于2002年的老牌工具Cain & Abel会让你眼前一亮。不同于现代抓包工具的被动观察&#xf…...

AIVideo效果对比展示:不同参数下的视频生成质量评测

AIVideo效果对比展示:不同参数下的视频生成质量评测 1. 开场白:参数设置对视频效果的影响 你有没有遇到过这样的情况:用AI生成视频时,明明输入的内容一样,但出来的效果却天差地别?有时候画面模糊不清&…...

OpenRGB:开源跨平台RGB灯光控制方案,告别多软件困扰实现设备统一管理

OpenRGB:开源跨平台RGB灯光控制方案,告别多软件困扰实现设备统一管理 【免费下载链接】OpenRGB Open source RGB lighting control that doesnt depend on manufacturer software. Supports Windows, Linux, MacOS. Mirror of https://gitlab.com/CalcPr…...

Phi-4-mini-reasoning企业落地案例:集成至内部知识库的逻辑问答模块

Phi-4-mini-reasoning企业落地案例:集成至内部知识库的逻辑问答模块 1. 项目背景与需求 企业内部知识库系统通常面临一个共同挑战:员工在查找专业问题时,往往需要花费大量时间筛选信息,特别是涉及数学计算、逻辑推理等需要多步分…...

二手车价格预测:特征工程比调参重要10倍!我的天池赛从800分降到490分的实战复盘

二手车价格预测实战:如何通过特征工程将MAE从800降到490 二手车市场向来以信息不对称为特点,价格波动大、影响因素复杂。对于数据科学家来说,准确预测二手车价格不仅是一个有趣的机器学习挑战,更是一个极具商业价值的实际问题。在…...

Qwen3-14B私有化效果:支持国密算法加密的API通信安全方案

Qwen3-14B私有化效果:支持国密算法加密的API通信安全方案 1. 私有部署镜像概述 Qwen3-14B私有部署镜像是基于通义千问大语言模型优化定制的专业解决方案,特别针对RTX 4090D 24GB显存配置进行了深度适配。这个镜像不仅提供了完整的运行环境和模型依赖&a…...

深求·墨鉴快速部署指南:3步搞定,体验优雅的文档图片转文字

深求墨鉴快速部署指南:3步搞定,体验优雅的文档图片转文字 1. 引言:当OCR遇见东方美学 在日常办公和学习中,我们经常需要将纸质文档、书籍图片或手写笔记转换为可编辑的电子文本。传统OCR工具往往只注重功能实现,而忽…...

别再纠结Copilot了!手把手教你用CodeGPT插件在IDEA里免费接入DeepSeek Coder

告别Copilot依赖:用DeepSeek CoderCodeGPT打造免费智能编程环境 在代码补全工具领域,GitHub Copilot长期占据主导地位,但其每月10美元的订阅费用让许多独立开发者和小团队望而却步。今天我要分享的这套方案,不仅完全免费&#xf…...