关于Qt乱码的解释和解决方案

先给出乱码的解决方案:

若是Qt5,则在pro文件中加入下面这段代码:

greaterThan(QT_MAJOR_VERSION, 4): {  
  QMAKE_CXXFLAGS += -execution-charset:utf-8
}

若是Qt4,则在main.cpp中加入下面这段代码:

#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))

 #ifdef Q_OS_LINUX

    QTextCodec *codec = QTextCodec::codecForName("UTF-8");

 #elif defined (Q_OS_WIN)

    QTextCodec *codec = QTextCodec::codecForName("GB2312");

 #endif

    QTextCodec::setCodecForLocale(codec);

    QTextCodec::setCodecForCStrings(codec);

    QTextCodec::setCodecForTr(codec);

#endif

关于Qt的乱码问题,以下是个人见解,可能有错误之处,欢迎指出。

要弄清楚Qt中的乱码问题,首先需要清除2个概念:

  1. 源码字符集(the source character set):源码文件是使用何种编码保存的
  2. 执行字符集(the execution character set):可执行程序内保存的是何种编码(程序执行时内存中字符串编码)

Qt为了保证跨平台,源码字符集统一采用的是带 BOM 的 utf-8格式,而在不同的系统上执行字符集的是不同的,Windows 一般用的GBK(GB2312),linux一般用的是不带BOM的UTF-8。

所以在windows系统下Qt5环境中,解决乱码的办法有pro文件中加

QMAKE_CXXFLAGS += -execution-charset:utf-8

或者在每个源文件的最上方加:

#pragma execution_character_set("utf-8")

这两者的原理都是将windows下的执行编码变成带BOM的utf-8格式,这样就和源码字符集一致,解决了乱码问题,这个方法在linux系统下也可以解决乱码问题,原理也是一致的。

但是在Qt4的环境下,上面2中方案的代码都是不识别的,所以在Qt4的环境下需要按以下方式解决乱码问题:

若是在windows系统下:

QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB2312"));

原理是将windows系统下QString中的中文字符用GB2312的编码存储,即将源码字符集变成GB2312的格式,这样源码字符集也和执行字符集一致了,都变成了GB2312。

若在linux系统下:

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

Linux下产生乱码的原因是源码字符集是带BOM的utf-8格式,而执行字符集是不带BOM的uft-8格式,这2种格式也是有区别的,同样会导致乱码。所以上面这句的原理是将QString存储的中文字符的源码字符集变成不带BOM的uft-8格式,这样源码字符集也和执行字符集一致了,都变成了不带BOM的uft-8格式。注意与上面的#pragma execution_character_set("utf-8")进行区别。

有一种万能的解决乱码的方式,那就是用QString::fromLocal8Bit函数,原理是QString全部以QTextCodec::setCodecForLocale函数指定的编码将字符串转成Unicode,在运行时再转成对应的执行编码,自然可以保持两者一致,解决乱码问题。若没有显示指定QTextCodec::setCodecForLocale,则windows下是GB2312,linux下是UTF-8。但是若主函数中用QTextCodec::setCodecForLocale(codec)指定的编码不对,在读取第三方输入的时候(如QProcess读取控制台消息),QString::fromLocal8Bit一样会导致乱码,例如:

在windows系统下,首先指定QTextCodec::setCodecForLocale("UTF-8"),

之后用QProcess读取控制台消息:

QString outputStr = QString::fromLocal8Bit(process.readAllStandardOutput());

由于windows上控制台的编码是GB2312,而这个时候Qt认为是UTF-8,自然导致了乱码,这个时候可以用如下方式解决:

QString outputStr = QTextCodec::codecForName("GB2312")->toUnicode(

process.readAllStandardOutput());

即直接说明当前的字段是GB2312编码即可。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值