彻底解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)

posted in: 系统相关 | 0

尊重作者,支持原创,如需转载,请附上原地址:

这篇文章有点长,内容有点多,如果时间急迫,可以直接翻页去末尾看结论。红色字体加粗的。(#^.^#)

一、Qt 环境设置

1、cpp或h文件从上传到后会显示乱码,原因是因为环境设置默认是utf-8,默认都是GBK.

我们使用的系统本地字符集编码为GBK。

2、环境下,Qt ,菜单->工具->选项->文本编辑器->行为->文件编码->默认编码,常用的选项有以下几个:

(简体中文系统默认指的是GBK编码)

GBK/-936-2000/CP936/MS936/-936

UTF-8

二、编码知识科普

Qt常见的两种编码是:UTF-8和GBK

★UTF-8: -8bit,允许含BOM,但通常不含BOM。是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码。UTF-8包含全世界所有国家需要用到的字符,是国际编码,通用性强。UTF-8编码的文字可以在各国支持UTF8字符集的浏览器上显示。如果是UTF8编码,则在外国人的英文IE上也能显示中文,他们无需下载IE的中文语言支持包。

★GBK是国家标准基础上扩容后兼容的标准。GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1。GBK包含全部中文字符,是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBD大。GBK是的扩展,除了兼容外,它还能显示繁体中文,还有日文的假名。

★GBK、等与UTF8之间都必须通过编码才能相互转换:

GBK、----UTF8

UTF8----GBK、

★在简体中文系统下,ANSI编码代表GBK/编码,ANSI通常使用0x80~0xFF范围的2个字节来表示1个中文字符。0x00~0x7F之间的字符,依旧是1个字节代表1个字符。(UTF-16)编码则所有字符都用2个字节表示。

三、编码转换

自带的记事本,无法查看UTF-8编码的文件到底有无BOM,需要使用其他文件编辑器,比如或者。

UTF-8与ANSI(即GBK)的互转,可以使用工具"文件另存为"或者编码转换工具对.cpp和.h源文件文本进行批量转换.

四、显示中文乱码的原因

我们使用的系统本地字符编码(Local字符集)为GBK。编译器分析出源文件字符编码之后,会进行解码再编码,将源字符集转码成执行字符集。执行字符集一般默认为使用本地字符编码(Local字符集)。

Qt5可以设置Local字符集,GBK/UTF-8

QTextCodec *codec = QTextCodec::codecForName("UTF-8");//或者"GBK",不分大小写
QTextCodec::setCodecForLocale(codec);

Qt5中内部采用字符集,utf-16编码。构造函数::(const char *str)默认使用(),将str所指的执行字符集从utf-8转码成utf-16。

由上面()可知,需要执行字符集编码为utf-8,然后以utf-8进行解码,再编码为utf-16才能获得正确的字符编码。显示中文乱码的原因其实就是转码方式与执行字符集不一致。(比如,源字符集为本地字符集GBK编码,以utf-8的方式进行解码,会导致获得错误的二进制编码,再将错误二进制转为utf-16就会出现乱码。)

五、Qt编码指定

Qt需要在main()函数指定使用的字符编码:

#include 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //设置中文字体  
    a.setFont(QFont("Microsoft Yahei", 9));
    //设置中文编码
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
#if _MSC_VER
    QTextCodec *codec = QTextCodec::codecForName("GBK");
#else
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
#endif
    QTextCodec::setCodecForLocale(codec);
    QTextCodec::setCodecForCStrings(codec);
    QTextCodec::setCodecForTr(codec);
#else
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForLocale(codec);
#endif
    return a.exec();
}

这里只列举大家最常用的3个编译器(微软VC++的cl编译器,Mingw中的g++,Linux下的g++),源代码分别采用GBK和无BOM的UTF-8以及有BOM的UTF-8这3种编码进行保存,发生的现象如下表所示。

情况1:指的是Local字符集为GBK

情况2:指的是Local字符集为UTF-8

#if defined(_MSC_VER) && (_MSC_VER >= 1600)    
# pragma execution_character_set("utf-8")    
#endif

或者添加 += /utf-8到您的.pro文件中。

六、测试案例

案例1、中文字符串测试

#if defined(_MSC_VER) && (_MSC_VER >= 1600)    
# pragma execution_character_set("utf-8")    
#endif
#include 
#include 
#include 
#include 
#include 
#include 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //设置中文字体  
    a.setFont(QFont("Microsoft Yahei", 9));
    //设置中文编码
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
#if _MSC_VER
    QTextCodec *codec = QTextCodec::codecForName("gbk");
#else
    QTextCodec *codec = QTextCodec::codecForName("utf-8");
#endif
    QTextCodec::setCodecForLocale(codec);
    QTextCodec::setCodecForCStrings(codec);
    QTextCodec::setCodecForTr(codec);
#else
    QTextCodec *codec = QTextCodec::codecForName("utf-8");
    QTextCodec::setCodecForLocale(codec);
#endif
    QString str(QObject::tr("1中文"));
    qDebug() << str;
    qDebug() << QStringLiteral("2中文");
    qDebug() << QString::fromLatin1("3中文");
    qDebug() << QString::fromLocal8Bit("4中文");
    qDebug() << QString::fromUtf8("5中文");
    qDebug() << QString::fromWCharArray(L"6中文");
    return a.exec();
}

当::("utf-8");时,

::和::是等效的。

当::("gbk");时,

::和::是不等效的。

案例2、QCom跨平台串口调试助手(Qt开源社区-致力于Qt普及工作! - qt qml linux 嵌入式 教程!)

源代码qcom.cpp,.cpp等文件用的是UTF-8编码(无BOM);但是qcom*.*文件用的是ANSI编码.在linux环境编译完全OK.

笔者环境的Qt +微软VC++编译器,环境设置用的是ANSI(即GBK)编码.编译源文件会报错.

错误提示"fatal error C1018: 意外的 #elif".

字符编码采用编码_系统文字编码_windows系统字符编码

解决方法由两种:

方法1:

把qcom的所有cpp和h文件都用工具转换成ANSI编码,main()函数使用::(::("GBK"));

方法2:

先把Qt 环境设置用的是UTF-8编码,

再把qcom的所有cpp和h文件都用工具转换成UTF-8+BOM编码,请注意,如果文件转换成UTF-8(无BOM),编译仍会失败.main()函数使用::(::("GBK"));//注意,此处仍是"GBK",不是"UTF-8"

重新编译,OK!

其它:

七、结论

环境下,Qt +微软VC++编译器,新建工程,

1、如果该工程不需要跨平台使用(只在win),那么工程设置请使用GBK的编码方式.

2、如果该工程要跨平台使用(win+linux),那么工程设置请使用UTF-8+BOM的编码方式.

另外,还需要在预编译头文件加入

CONFIG += c++11
#可以在项目中使用预编译头文件的支持
CONFIG += precompile_header 
#预编译头文件路径
PRECOMPILED_HEADER = $$PWD/stdafx.h 

#if defined(_MSC_VER) && (_MSC_VER >= 1600)    
# pragma execution_character_set("utf-8")    
#endif

或者添加 += /utf-8到您的.pro文件中。

3、Linux环境下,Qt +gcc,新建工程,

没有GBK编码可选,默认是UTF-8(无BOM)编码方式,考虑到跨平台,建议选择UTF-8+BOM的编码方式.

★★★★★★★★★★★★★★★综上所述,解决乱码的方法概括如下:★★★★★★★★★★★★★★★★★★★★★

1、如果IDE是Qt ,把它的环境设置为“UTF-8+BOM”编码。

2、如果IDE是 ,请下载插件,名称是 (with BOM),所有源文件和头文件都会保存为“UTF-8+BOM”编码。

3、如果编译器是MSVC,请在预编译头.h文件加入

#if () && ( >= 1600)

# set("utf-8")

#endif

4、源码文件main函数入口设置中文编码:

#

#

int main(int argc, char *argv[])

a(argc, argv);

//设置中文字体

a.(QFont(" Yahei", 9));

//设置中文编码

#if (

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注