VS+QT编译环境中字符乱码问题解决方法

 更新时间:2024年01月22日 11:05:30   作者:北冥有鱼丶丶  
编码就是把⼀个字符编码成二进制码存起来的方式,而解码就是把这个二进制码按照原本编码的规则还原成原来的字符,这篇文章主要介绍了VS+QT编译环境中字符乱码问题详解,需要的朋友可以参考下

字符乱码问题详解

在解释字符乱码问题之前,我们需要先理清一些基本概念

1 编码字符集与字符编码方式

编码字符集

编码字符集是所有字符以及对应代码值的集合。编码字符集中的每个字符都对应一个唯一的代码值。常见的编码字符集:ASCII字符集、GBXXXX字符集、BIG5字符集、Unicode字符集等。

字符编码方式

编码字符集中只规定了字符的代码值并未规定具体如何存储,字符编码方式解决了字符在计算机中如何存储的问题,它是将编码字符集中的字符代码值转换为实际的存储字节序列的一种映射规则。常见字符编码方式:ASCII编码、GBXXXX编码、BIG5编码、UTF-8编码、UTF-16编码、UTF-32编码等。每种编码字符集至少对应一种字符编码方式,也可以对应多种编码方式。

什么是字符的编码与解码?
编码就是把⼀个字符编码成二进制码存起来的方式,而解码就是把这个二进制码按照原本编码的规则还原成原来的字符。

源字符集: 源文件字符集是指源文件保存时按源字符集编码方式编码后的字符集。VS2019源字符集编码格式默认是GBK格式,在利用VS编写代码时,源代码会自动编码为GBK字符集。

执行字符集: 程序运行时所使用的字符集,编译器会将源字符集先按照源字符集编码方式进行解码,再将解码后得到的字符按照执行字符集编码方式编码为执行字符集。执行字符集一般默认使用Windows系统本地字符编码,若是简体中文系统,则是GBK或GB2312字符集。

2 字符乱码原因

在编程中我们给某个函数输入中文字符串的时候,在运行的时候中文字符串往往就会变成乱码,这是因为编码方式与解码方式不一致造成的。

例:
VS+QT编译环境中,如果直接将中文字符串传给QT函数时,会出现乱码:

QString s("你好");//乱码
qDebug() << "路漫漫其修远兮";//乱码

原因在于这些中文字符串被GBK编码为源字符集,编译器会先采用GBK将这被GBK编码的源字符集解码,再用GB2312编码为执行字符集,而Qt5内部采用Unicode字符集,UTF-16编码,QT中的函数会将执行字符集使用UTF-8解码,再使用UTF-16编码为unicode字符集,QString内部使用UTF-8对执行字符集进行解码的时候,与执行字符集编码格式不一致,肯定会出现乱码现象。

为什么英文字符就不会出现乱码现象呢?

英文字符通常都是ASCII字符编码,常见的字符编码都会以某种形式“兼容”ASCII编码,而我们接触比较多的UTF-8和GBK则是完全兼容ASCII,也就是ASCII编码的数据,在UTF-8、GBK中会是一样的数字形式(一个字节)。即
AB在ASCII编码中对应的是0x41和0x42,在GB2312和UTF-8中还是0x41和0x42,所以对于AB这两个字符用GB2312编码为0x41和0x42后,采用UTF-8再进行解码,得出来的仍然是AB,所以不会出现乱码。

3 字符乱码解决方案

(1)使用QStringLiteral宏

从“字符串常量”创建QString对象

qDebug() << QStringLiteral("路漫漫其修远兮");

QStringLiteral宏它只能处理常量。

(2)使用fromLocal8Bit()函数

fromLocal8Bit是Qt 中QString 类的一个成员函数,用于将使用本地编码的字符串转换为 QString 对象的内部 Unicode编码。

qDebug() << QString::fromLocal8Bit("路漫漫其修远兮");

使用QStringLiteral宏和fromLocal8Bit()函数输出的字符串还带有双引号:

使用下面的这两个方法可以解决这种问题。

(3)使用#pragma execution_character_set(“utf-8”)

源程序中加上如下指令,将源文件的可执行字符集编码方式设置为utf-8

#pragma execution_character_set("utf-8")
 qDebug() << "路漫漫其修远兮";

(4)使用u8关键字

C++17到来后出现了u8关键字,表示一个字符串的可执行字符集编码方式是UTF-8编码

qDebug() << u8"路漫漫其修远兮"

到此这篇关于VS+QT编译环境中字符乱码问题详解的文章就介绍到这了,更多相关VS QT字符乱码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Qt项目打包的实现步骤

    Qt项目打包的实现步骤

    本文主要介绍了Qt项目打包的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • C语言中结构体和共用体实例教程

    C语言中结构体和共用体实例教程

    这篇文章主要给大家介绍了关于C语言中结构体和共用体的相关资料,结构体是一种自定义的复合数据类型,共用体也叫联合体,使几个不同类型的变量共占一段内存(相互覆盖),需要的朋友可以参考下
    2021-06-06
  • C语言线性代数算法实现矩阵示例代码

    C语言线性代数算法实现矩阵示例代码

    这篇文章主要为大家介绍了使用C语言线性代数的算法来实现矩阵示例代码,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2021-10-10
  • C++高精度计时的几种方法总结(测试函数运行时间)

    C++高精度计时的几种方法总结(测试函数运行时间)

    本文介绍了C++中常用的几种程序计时方法,包括clock()函数、GetTickCount()、QueryPerformanceCounter()以及C++11中的chrono库函数,这篇文章主要介绍了C++高精度计时的几种方法,需要的朋友可以参考下
    2024-09-09
  • VSCode之CMake使用小结

    VSCode之CMake使用小结

    本文主要介绍了VSCode之CMake使用小结,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-03-03
  • C语言:十进制,BCD码互换详解

    C语言:十进制,BCD码互换详解

    这篇文章主要介绍了C语言十进制,BCD码互换实例,小编觉得这篇文章写的还不错,实例简单明了,需要的朋友可以参考下
    2021-09-09
  • VC实现对话框窗口任意分割

    VC实现对话框窗口任意分割

    最近写MFC的程序,想在对话框里实现窗口的任意分割。现在网络资料一大抄,找个东西实在麻烦。总算这个很简单,很快就搞定了,写下来做个笔记。
    2015-06-06
  • C++中I/O模型之select模型实例

    C++中I/O模型之select模型实例

    这篇文章主要介绍了C++中I/O模型的select模型,实例讲述了I/O模型的用法,具有一定的参考借鉴价值,需要的朋友可以参考下
    2014-10-10
  • C++使用HDF5库实现将h5图像转为tif格式

    C++使用HDF5库实现将h5图像转为tif格式

    这篇文章主要为大家详细介绍了C++ 语言如何通过hdf5库与gdal库实现将.h5格式的多波段HDF5图像批量转换为.tif格式,有需要的可以参考一下
    2024-12-12
  • C/C++如何获取当前系统时间的实例详解

    C/C++如何获取当前系统时间的实例详解

    这篇文章主要介绍了 C/C++如何获取当前系统时间的实例详解的相关资料,这里提供了几种实现方法,帮助大家实现这样的功能,需要的朋友可以参考下
    2017-08-08

最新评论