Qt与MSVC中文乱码问题的解决方案

2023-11-02

一、问题是什么?

在学习Qt编程的过程中,大多数人都遇到过中文乱码的问题。总结起来有三类:

1. Qt Creator中显示的汉字变为乱码,编辑器上方有“Could not decode "..." with "UTF-8"-encoding. Editing not possible.”的错误提示。此时,出现乱码的文档是不可编辑的。如下图所示,“你好中文!”这5个中文字符变成了乱码

2. Qt Creator中显示的汉字正常,但编译的时候会出现“常量中有换行符”等一系列错误报警。其实,这也是文字编码的问题。如下图所示:

Qt与MSVC中文乱码问题的解决方案 - liuweilhy - 鸿远 

3. 编译时未报错,但生成的程序中文乱码。如下图所示:

Qt与MSVC中文乱码问题的解决方案 - liuweilhy - 鸿远 

其中,第3条是网上提问的最多的,几乎是所有使用MSVC的初学者都会碰到的问题很多回答是针对Qt4版本的,Qt5中不可用。

二、为什么会出现这些问题?

在解决问题之前,字符编码知识是必需的。你要知道ASCII、GB2312、GBK、Unicode、UTF-8、UTF-16、BOM是怎么回事。此外,你还要明白源码字符集、执行字符集是什么。详细内容可以在网上搜索一下,俯拾即是。

1. Qt Creator的编辑器默认使用UTF-8(代码页65001)编码来读取文本文件。而Visual Studio保存文件时默认采用的是本地编码,对于简体中文的Windows操作系统,这个编码就是GB2312(代码页936)。如果使用Qt Creator读取由Visual Studio创建的文件,那么编辑器就会以UTF-8编码格式读取GB2312编码格式的文件,出现中文乱码,因为这两套编码系统对汉字编码是不同的。至于英文部分不会乱码,是因为UTF-8和GB2312在单字节字符部分是兼容的。

2. MSVC在编译时,会根据源代码文件有无BOM来定义源码字符集。如果有BOM,则按BOM解释识别编码;如果没有,则使用本地字符集,对于简体中文的Windows操作系统就是GB2312。那么,当MSVC遇到一个没有BOM的UTF-8编码的文件时,它通常会把文件看作GB2312的来处理。如果文件全是英文没有问题,但如果包含中文,编译器就会出现误读。这种情况下,Qt Creator编辑器是正常的。但对于MSVC编译器,原代码会被它认识成下图这个样子:

Qt与MSVC中文乱码问题的解决方案 - liuweilhy - 鸿远 

这是我用EverEdit指定本地编码重读后的结果,可以看到汉字出错,末端的引号也没了。

在UTF-8中,一个中文字符(汉字或标点符号)占用3个字节,“你好中文!”这5个中文字符共占用15个字节;而在GB2312中,一个中文字符(汉字或标点符号)占用2个字节,这时,MSVC把UTF-8编码的15个字节加上后面1个字节的英文引号合成16个字节当作8个中文字符处理。之后,MSVC在这一行里直到末尾换行符出现都没有找到下一个引号,它以为你把字符串在这里敲回车换行了,于是报警称“常量中有换行符”,并引出一系列的错误。

不过,当以无BOM的UTF-8编码的字符串正好凑够偶数个字节时(比如偶数个汉字,或奇数个汉字加奇数个英文字母),编译器通常不会报警,因为它以为用GB2312编码读出的是正确的。

3. 不管源文件是何种编码,只要MSVC能够正确识别,就可以通过编译。但MSVC的执行字符集默认是本地字符集。对我们来说,它生成的可执行文件中的文字是GB2312编码的。而生成的Qt程序以UTF-8编码来识别GB2312编码的文字,对于“你好中文!”这几个字符,采用GB2312编码后再以UFT-8编码来读取,就会变成如下的乱码:

Qt与MSVC中文乱码问题的解决方案 - liuweilhy - 鸿远

当以无BOM的UTF-8编码的字符串正好凑够偶数个字节时(比如偶数个汉字,或奇数个汉字加奇数个英文字母),反而不会出现乱码。那是因为,编译器用GB2312编码读出的乱码本身就是UTF-8编码的,现在又用UTF-8解读,自然就正确了。这纯粹是歪打正着。

三、怎么解决这些问题?

首先,你要确定采用哪种源码字符集。你有两个选择:

1. 采用本地编码字符集(不推荐,跨平台时会比较麻烦,但在Visual Studio环境下配合Add-in工具编程比较方便);

2. 采用UTF-8编码字符集(推荐,适合跨平台)。

1 “采用本地编码字符集”方案,解决方法如下:

首先,要把项目中所有的头文件和源文件全都转换成GB2312编码保存。

1. 第1个问题:在Qt Creator中打开项目,点击左侧工具栏“项目”,在“编辑器”选项卡中把“默认编码”改成“GB2312”。如下图所示:

Qt与MSVC中文乱码问题的解决方案 - liuweilhy - 鸿远 

话说回来,既然选择本地字符集,大致上是放弃跨平台了。与其用轻量级的Qt Creator,不如用Visual Studio作开发环境更好。

2. 第2个问题:“常量中有换行符”等一系列报警已不存在了。

3. 第3个问题:在字符串常量上加QStringLiteral宏或QString::fromLocal8Bit函数,如:

QString str = "你好中文!";

改为:

QString str = QStringLiteral("你好中文!");

或者:

QString str = QString::fromLocal8Bit("你好中文!");

不过,在这两种形式下,你都无法用tr方法来创建翻译了。

2 “采用UTF-8编码字符集”方案,解决方法如下:

首先,要把项目中所有的头文件和源文件全都转换成UTF-8+BOM编码保存。

1. 第1个问题不存在了。

2. 第2个问题也不存在了。

3. 第3个问题,你也可以用上个方案中的方法来解决,但有更好的方法。那就是要用到中文字符的头文件和源文件开头加上MSVC的一个宏:

#if _MSC_VER >= 1600

#pragma execution_character_set("utf-8")

#endif

这个宏告诉MSVC,执行字符集是UTF-8编码的,别瞎整成GB2312的!还有个好处,就是能用tr包中文,方便日后的翻译。最终效果如下:

Qt与MSVC中文乱码问题的解决方案 - liuweilhy - 鸿远 

 



FROM:  http://liuweilhy.blog.163.com/blog/static/11405670201510901627229/



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt与MSVC中文乱码问题的解决方案 的相关文章

  • 回文词(Uva 401)

    输入一个字符串 判断它是否为回文串以及镜像串 输入字符串保证不含数字0 所谓回文串 就是反转以后与原串相同 如abba和madam 所谓镜像串 就是左右镜像之后和原串相同 如2S和3AIAE 注意 并不是每个字符在镜像之后都能得到一个合法字
  • 以给定值x为基准将单链表分割为两部分,所有小于x的结点都排在大于或等于x的结点之前。

    include LinkList cpp 现单链表的各种基本运算的算法文件单链表的基本运算算法 yyy zxc的博客 CSDN博客 void Split02 LinkNode L ElemType x LinkNode p L gt nex
  • LayUI中的内置模块之 图片/文件上传 layui.upload

    前言 最近在准备找工作的事项 但是作为一个后台也是需要了解一些前端框架的 就目前的来说有大火的VUE 但是VUE还是存在一定的学习成本 所以决定先从对后台友好的LayUI开始入手先做一些小项目练练手 后面会考虑使用VUE ElementUI
  • Tomcat8版本--后台管理弱口令登录

    一 开启vulhub 找到tomcat文件 环境下载并建立 在tomcat8目录下输入以下命令 docker compose build 若出现镜像跳过的问题 直接输入下面的命令 docker compose up d 二 打开网页 第三步
  • MATLAB统计矩阵中非0元素的个数

    A 1 2 0 0 3 3 统计矩阵A中非0元素的个数 sum sum A 0
  • Xml的解析

    文章目录 java的配置文件 dom4j的使用 以下两段代码都有对dom4j的使用 xpath的使用 java的配置文件 在同一个包 从当前包里寻找db properties Demo01 class getResourceAsStream
  • tcpdump: Couldn‘t find user ‘tcpdump‘问题解决

    直接vi etc passwd 加入以下一行 tcpdump x 72 72 sbin nologin 就可以了
  • C++ 移动语义

    C 11 移动语义 首先 移动语义和完美转发这两个概念是在C 的模板编程的基础上 新增的特性 主要是配合模板来使用 本篇会从C 的值类型 到移动拷贝与移动赋值来理解移动语义与完美转发 文章目录 C 11 移动语义 C 的值类型 右值引用与移
  • 51单片机STC15W4K56S4控制步进电机28BYJ-48正反转

    步进电机28BYJ 48 12V 介绍 首先 我们看下步进电机28BYJ 48 12V 外观图 如下 28BYJ 48 12V 含义如下 28表示电机直径28毫米 B表示电机 Y表示永磁 J表示带减速箱 48表示四相八拍 下面解释下 4 相
  • 数组截取--slice()

    待补充
  • 结构体的定义以及初始化

    一 结构体定义类型 变量的定义 struct是关键字 是结构体类型的标志 在结构体里可以定义相应的成员信息 同时 结构体同样要以分号结尾 struct person char name 20 char sex 20 int age int
  • eclipse 找不到 tomcat 的解决方案

    前言 查了很多教程上配置tomcat时都是直接 File gt gt New gt gt Other gt gt Server gt gt Server gt gt Apache gt gt tomcat 然而我发现在这两个eclipse中
  • 日志大文件拆分

    前言 生产环境没设置好日志文件大小的最大值 导致日志文件过大 普通编辑器根本没法打开 要排查日志改怎么办 拆分日志大文件 如何拆分 split命令专门用来将一个大文件分割成很多个小文件 我把split命令的选项做一个简要说明 选项 含义 b
  • Python opencv库 tkinter 设计屏幕录制工具

    有时 我们在电脑上需要录屏 或制作gif动画 用于演示电脑操作等 如何使用Python来实现 目录 1 使用cv2库生成视频 2 使用tkinter选择录制区域 3 再次实现 4 最终的程序 5 拓展 创建gif动画 1 使用cv2库生成视
  • Docker日志日期时间精确查询

    docker logs since 2020 07 30T10 14 00 until 2020 07 30T10 15 00 tomcat80 这条代码可以通过2个时间来查询指定范围的时间日志 since起始时间 你要从什么时候开始查询
  • 【数据结构】UnionFind 并查集-2

    数据结构源码 UnionFind1 接口 public interface UnionFind int getSize boolean isConnected int p int q void unionElements int p int

随机推荐

  • 华大HC32L176与三相四线计量模块JSY_333通讯例程以及对三相三线认识误区

    在某宝购买这个产品后 需要编写程序读取数据 这款产品可以使用TTL和RS485进行通讯 我用的是用华大单片机HC32L176 首先对串口进行初始化 程序可以自行下载 链接 https pan baidu com s 1FD2VecV64ZH
  • 从端到端打通模型端侧部署流程(NCNN)

    文章目录 背景介绍 为什么要做端侧推理 端侧深度学习部署流程 一条主要技术路线 ONNX NCNN框架 NCNN的官方介绍 NCNN问题解决 NCNN使用样例 快速在NCNN框架下验证自己的模型 一般流程 YOLOv5的demo测试 全新部
  • CGSS中国综合社会调查

    数据详情 1 包含数据库和问卷 2 数据包含的年份为2003 2005 2006 2008 2010 2011 2012 2013 2015 2017 3 2017年数据为SPSS和STATA 14版 CSV EXCEL 编码表 4 15年
  • 8.14 ARM

    1 练习一 text 文本段 global start 声明一个 start函数入口 start start标签 相当于C语言中函数 mov r0 0x2 mov r1 0x3 cmp r0 r1 beq stop subhi r0 r0
  • python的类写法_python类写法

    广告关闭 腾讯云11 11云上盛惠 精选热门产品助力上云 云服务器首年88元起 买的越多返的越多 最高返5000元 在python中这一点仍然成立 in class fatboy object pass in fb fatboy in pr
  • 刷脸发甚至改变整个支付行业和零售行业

    在今年4月17日 蚂蚁金服在北京发布新一代刷脸支付产品 蜻蜓2 0 并宣称未来将会投入30亿让刷脸支付全国普及 助力商家数字化 让商家快速结付 提高商家运营效率 为顾客便利服务 为商家引流 支付宝蜻蜓二代接入刷脸即会员等数字化经营能力 试点
  • vue el-option只回显数字问题

    1 value前面没有加冒号说明是字符串 加个冒号即可回显label名称 2 后端返回的值可能已经将id类型返回为String 此时转换为number即可回显 3 也可用v for循环渲染选项 回显时肯定能回显label名称
  • 机器人避障路径规划--基于人工势场算法

    机器人避障路径规划 基于人工势场算法 机器人避障路径规划是机器人导航和控制中的一个基本问题 它的目标是在给定环境中找到一条安全可行的路径 使得机器人能够从起点到达目标点 并尽可能地避免与环境发生碰撞 人工势场算法是一种常用的机器人避障路径规
  • error: could not delete '/usr/local/lib/python3.6/site-packages/pip/_internal/configuration.py': Per

    brew install python 报错 error could not delete usr local lib python3 6 site packages pip internal configuration py Permis
  • 黑马程序员Javaweb学习笔记02【request和response】

    该博客主要记录在学习黑马程序员Javaweb过程的一些笔记 方便复习以及加强记忆 系列文章 JavaWeb学习笔记01 BS架构 Maven Tomcat Servlet JavaWeb学习笔记02 request和response Jav
  • 【三维语义分割】PointNet++ (二):模型结构详解

    本文为博主原创文章 未经博主允许不得转载 本文为专栏 python三维点云从基础到深度学习 系列文章 地址为 https blog csdn net suiyingy article details 124017716 本节主要介绍Poin
  • 电机的堵转检测及处理

    基于L298N控制的电机的堵转检测及其处理 一 L298N原理 二 电机堵转检测 三 电机堵转处理 一 L298N原理 1 L298N datasheet 2 使用须知 工作电压高 最高工作电压可达46V 输出电流大 瞬间峰值电流可达3A
  • jeesite框架分析理解

    前文 jeesite代码生成器的使用 实例 报销表 地址 http blog csdn net m0 38021128 article details 68490920 前文中使用了jeesite框架的代码生成功能实现了一个小实例 但是实际
  • STM32CubeMX—串口空闲中断+DMA接收

    一 串口中断通信 串口中断方式的特点 发送数据时 将一字节数据放入数据寄存器DR 接收数据时 将DR的内容存放到用户存储区 中断方式不必等待数据的传输过程 只需要在每字节数据收发完成后 由中断标志位触发中断 在中断服务程序中放入新的一字数据
  • iOS 微信发布 8.0.12 正式版,寂寞来袭

    今天微信突然更新8 0 12正式版 我马上更新 更新完后并没有发现什么新功能 我就赶紧发文告诉大家 大家快去更新 更新看看这次更新了什么 我在AppStore商店更新完毕后就大概看了一下 并没有什么实质性的功能 可能内测功能还是内测人使用吧
  • org.apache.catalina.core.ApplicationContext.log ssi: Can‘t find file: /index.htmlERROR ErrorPageFil

    自己配置的tomcat 部署应用时提示错误信息 org apache catalina core ApplicationContext log ssi Can t find file index html ERROR ErrorPageFi
  • 如何设计一个高并发系统?

    原创 苏三呀 苏三说技术 2023 09 08 08 21 发表于四川 收录于合集 系统设计3个 大家好 我是苏三 又跟大家见面了 前言 最近有位粉丝问了我一个问题 如何设计一个高并发系统 这是一个非常高频的面试题 面试官可以从多个角度 考
  • 【VUE2】VUE2基础知识和原理--超详细--超简介--零基础(一)

    vue基础知识和原理 1 初识Vue 想让Vue工作 就必须创建一个Vue实例 且要传入一个配置对象 demo容器里的代码依然符合html规范 只不过混入了一些特殊的Vue语法 demo容器里的代码被称为 Vue模板 Vue实例和容器是一一
  • 兼容火狐--常见问题修改

    此文为本人在实际工作中遇到的情况做的记录 所以比较乱 主要用于自己日后查看 如果对大家有帮助 当然也更好 最普遍的情况 当遇到功能不好使的情况 首先按f12看控制台有没有报错 A如果有定位错误 常见错误 window frames ifra
  • Qt与MSVC中文乱码问题的解决方案

    一 问题是什么 在学习Qt编程的过程中 大多数人都遇到过中文乱码的问题 总结起来有三类 1 Qt Creator中显示的汉字变为乱码 编辑器上方有 Could not decode with UTF 8 encoding Editing n