博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux qt默认编码方式是什么,QT编码方式
阅读量:6972 次
发布时间:2019-06-27

本文共 6545 字,大约阅读时间需要 21 分钟。

字符串常量、"中文"是传统的char类型的窄字符串、在使用的时候只需要告诉QString这两个汉字采用的编码构造QString。

const char * str = "中文";

QString qstr = str; //相当于调用QString::QString(const char * str)初始化一个QString

概念1:源文件是有编码的

"中文" 在不同的编码下对应不同的二进制形式

可能在GBK编码下是:ce d2 ca c7

在Latin-1编码下是:ba ba d7 d6

概念2:QString内部采用的是Unicode

一个问题,源代码中假如有4个字节"\xce\xd2\xca\xc7“该怎么转换成Unicode并存储在QString内。按照GBK、BIG5、Latin-1还是其他方式...

在你不告诉它的情况下,它默认选择了Latin-1,于是4个字符"ÎÒÊÇ"的unicode码被存进了QString中。最终,4个Latin字符出现在你期盼看到2中文字符的地方,所谓的乱码出现了

解决方式

问题很简单,当你需要从窄字符串 char*

转成Unicode的QString字符串的,你需要告诉QString你的这串char*

中究竟是什么编码?GBK、BIG5、Latin-1

理想情况就是:将char* 传给QString时,同时告诉QString自己的编码是什么

就像下面的函数一样,QString的成员函数知道按照何种编码来处理 C 字符串

QString QString::fromAscii ( const char * str, int size = -1 )

QString QString::fromLatin1 ( const char * str, int size = -1 )

QString QString::fromLocal8Bit ( const char * str, int size = -1 )

QString QString::fromUtf8 ( const char * str, int size = -1 )

QString 只提供了这几个成员函数,远远满足不了大家的需求,比如,在简体中文Windows下,local8Bit是GBK,可是有一个char串是 BIG5 或 Latin-2怎么办?

可以使用强大的QTextCodec,首先QTextCodec肯定知道自己所负责的编码的,当你把一个char串送给它,就能正确将其转成Unicode

QString QTextCodec::toUnicode ( const char * chars ) const

可是这个调用太麻烦了

想直接

QString a= str;

QString a(str);

这样一来肯定没办法同时告诉 QString 你的str是何种编码了,只能通过其他方式了。

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

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

设置QString默认采用的编码。而究竟采用哪一个,一般来说就是源代码是GBK,就用GBK,源代码是UTF-8就用UTF-8。但有一个例外,如果你保存成了带BOM的UTF-8而且用的微软的cl编译器,此时仍是GBK。

总结

QString内部采用的是 Unicode,它可以同时存放GBK中的字符"我是汉字",BIG5中的字符"扂岆犖趼"

以及Latin-1中的字符"ÎÒÊǺº×Ö"。

当你需要从窄字符串 char* 转成Unicode的QString字符串的,你需要告诉QString你的这串char*

中究竟是什么编码?GBK、BIG5、Latin-1?

在你不告诉它的情况下,它默认选择了Latin-1,于是8个字符"ÎÒÊǺº×Ö"的unicode码被存进了QString中。最终,8个Latin字符出现在你期盼看到4中文字符的地方,

所谓的乱码出现了。

网上有很多方法介绍直接在main.cpp里设置:

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

QTextCodec::setCodecForTr(codec);

QTextCodec::setCodecForLocale(codec);

QTextCodec::setCodecForCStrings(codec);

其实这在某些情况下也是有问题的,因为程序可能读到系统的中文路径,或者调用中文路径下的外部程序,这时候如果系统是gb2312就有问题了。

因为中文路径的编码是采用utf-8存到QString里的,系统读中文路径解码的时候采用的却是系统的gb2312,所以会调不起带中文路径的外部程序。

以上问题下面方法可以解决:

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

QTextCodec::setCodecForTr(codec);

QTextCodec::setCodecForLocale(QTextCodec::codecForLocale()); //设置GBK到本地

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

对于外部字符串编码解码全部采用本地编码。

在QT5中,加上这句,源文件使用UTF-8编码,不带BOM

QApplication a(argc, argv);

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

ANOTHER

一般在Window开发环境里,是GBK编码,在Linux开发环境里,是utf-8编码,关于编码的定义,

我就不这里多说了,网上有一大堆资料可以查看。

qt对默认的是unicode编码,在Window开发环境里,比较通用的写法是:

在main.cpp文件中加入:

1.

QTextCodec *gbk =

QTextCodec::codecForName("gb18030");

2.

QTextCodec::setCodecForTr(gbk);

3.

QTextCodec::setCodecForLocale(gbk);

4.

QTextCodec::setCodecForCStrings(gbk);

第一行:定义gb18030编码格式

第二行: 这个函数的作用是设置传给tr函数时的默认字符串编码,GUI设计中最常用的一种。

第三行:这个函数主要用于设置和对本地文件系统读写时候的默认编码格式。比如通过流读取一个文件内容时的编码格式。或者通过qDebug()输出打印信息时的编码。

第四行:这个函数主要是用在字符常量或者QByteArray构造QString对象时使用的一种编码方式。

同理,在Linux开发环境里, 通用的写法是:

QTextCodec

*utg8 = QTextCodec::codecForName("utf-8");

QTextCodec::setCodecForTr(utg8 );

QTextCodec::setCodecForLocale(utg8 );

QTextCodec::setCodecForCStrings(utg8 );

一般我们做GUI设计的时候,

用到最多的也就是setCodecForTr()这个函数了,其他可以根据自己所用到的区域在设置,不过,为了通用编码,以便忘记了编码格式而弄的自己头痛,

建议还是把这三个统一设置一下吧,尽量避免中文乱码出现的概率。

下面讲一下关于编码转换问题

QT中的QString内容使用Unicode作为文本编码。但是实际系统中通常采用的是其他编码,例如GBK,utf8等。为了便于兼容这些格式,QT中还设置了两个字符串类型:

QCString类: C类型字符串,必须以0结尾,也就是中间不能含有0. 例如GBK编码的字符串

QByteArray类: 中间可以含有0.例如utf8编码的字符串

在设置下面的代码基础上:

QTextCodec *gbk =

QTextCodec::codecForName("gb18030");

QTextCodec *utg8 = QTextCodec::codecForName("utf-8");

QTextCodec::setCodecForTr(gbk);

QTextCodec::setCodecForLocale(gbk);

QTextCodec::setCodecForCStrings(gbk);

1. UTF-8 转换 GBK

QString U2G(QString utfStr)

{

return gbk->toUnicode(utfStr.toLocal8Bit());

}

2 GBK 转换 UTF-8

QString U2G(QString gbkStr)

{

return utg8->toUnicode(gbkStr.toUtf8());

}

-----------------------------------------------------------------------------------

QTextCodec *gbk = QTextCodec::codecForName("gb18030");

QTextCodec

*utf8 = QTextCodec::codecForName("utf-8");

QTextCodec::setCodecForTr(gbk);

QTextCodec::setCodecForLocale(gbk);

QTextCodec::setCodecForCStrings(gbk);

QFile

file("../test.txt");

file.open(QIODevice::ReadOnly);

QByteArray

readByte = file.readAll();

QString

readStr = utf8->toUnicode(readByte.data());

file.close();

QString

utfStr =

QObject::trUtf8(readByte); //utf-8

QString

gbkStr =

QObject::tr("中文"); // gbk

QString

utf2gbk =

gbk->toUnicode(readStr.toLocal8Bit()); // utf8 conver gbk

QString

gbk2utf1 =

utf8->toUnicode(utf2gbk.toUtf8()); // gbk convert utf8

QString g2u

=

gbk->toUnicode(gbk->fromUnicode(readStr)); // gbk convert utf8

qDebug()

<< "gbk:" << gbkStr;

qDebug()

<< "utf8:" << utfStr;

qDebug()

<< "readStr:" << readStr;

qDebug()

<< "read_size:" << readByte.length();

qDebug()

<< "utf2gbk:" <

readStr.toLocal8Bit().length();

qDebug()

<< "gbk2utf8-1:" << gbk2utf1 << " length: "

<< utf2gbk.toUtf8().length();

qDebug()

<< "g2u" << g2u << "length:" <<

gbk->fromUnicode(utfStr).length();

QLabel

*label = new QLabel(utf2gbk);

label->show();

从Qt5开始只剩下setCodecForLocale这一个了,只是影响Qt对toLocal8Bit相关函数的编码方式(在源码里写非英文,官方推荐“\xE4\xBD...”这种)good

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

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

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

网上很多人一碰到编码问题就无脑的Copy上面3行……

从Qt5开始只剩下setCodecForLocale这一个了,只是影响Qt对toLocal8Bit相关函数的编码方式

{

// Qt默认会使用本机编码,所以对于中文系统,下面这句设置是多余的

QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));

QString str1("你好Hello");

QByteArray bLocal = str1.toLocal8Bit(); // 受setCodecForLocale影响,会转换为设定的编码。如果本机不支持指定编码,则会按toLatin1处理

QByteArray baLatin1 = str1.toLatin1(); // 不受setCodecForLocale影响,强制转换为ISO-8859-1编码

QByteArray bUtf8 = str1.toUtf8(); // 不受setCodecForLocale影响,强制转换为UTF-8编码

qDebug() <

qDebug() <

qDebug() <

qDebug() <

QString str2 = QString::fromLocal8Bit(bLocal);

qDebug() <

str2 = QString::fromLatin1(bLocal);

qDebug() <

// 字节流来自UTF-8

str2 = QString::fromUtf8("\xE4\xBD\xA0\xE5\xA5\xBD\x48\x65\x6C\x6C\x6F");

qDebug() <

// Qt默认采用UTF-8处理字符串,所以不用显式地去调用fromUtf8

str2 = QString("\xE4\xBD\xA0\xE5\xA5\xBD\x48\x65\x6C\x6C\x6F");

qDebug() <

}

在Qt中,QString会用UTF-16编码存储,而qDebug()等I/O函数会以UTF-8编码处理。

其实转换后的字节流是正确的,只是显示时用了和字节流不同的编码方式处理导致乱码

所以当要在Qt中输入输出非UTF-8字符串时应该先转换一下

在源码中要写入非英文字符的话建议使用转义的方式,也就是上面“\xE4\xBD...”这种,这也是官方推荐的方式

为了方便将字符串转换为UTF8转义字符,写了一个小工具

2014-5-6补充:

从vs2010sp1和vs2013开始就已经支持UTF-8的源码文件了,只用在工程里加入一句"#pragma

execution_character_set("UTF-8")"即可。不用再做上面的转义了。

http://blog.csdn.net/aqtata/article/details/9184741

你可能感兴趣的文章
SQLite.swift —— 纯 Swift 封装的 SQLite 框架
查看>>
《深入理解Spark:核心思想与源码分析》——3.11节ContextCleaner的创建与启动
查看>>
“淘宝心选”上线!taobaoxinxuan.xin被阿里巴巴收购
查看>>
天猫黑科技秘密全公开!人脸识别、AR交互、3D物体云识别...
查看>>
《深入浅出iPhone/iPad开发(第2版)》——……因为每个人都想要一个!
查看>>
《Adobe After Effects CS4经典教程》——1.5 对合成图像作动画处理
查看>>
Centos7.x系统网卡启动报错问题排查
查看>>
ROCBOSS v2.1.0 正式发布,PHP 微社区
查看>>
《微信公众平台开发:从零基础到ThinkPHP5高性能框架实践》——1.3 微信公众平台的使用...
查看>>
PostGIS 坐标转换(SRID)的边界问题 - ST_Transform
查看>>
苹果Mac 30周年:那些改变世界的人和Mac电脑
查看>>
倪光南:建议政府停止采购和使用“ Win10 政府版”
查看>>
Arquillian OSGi 2.2.1.Final 发布
查看>>
《深入理解ElasticSearch》——第2章查询DSL进阶 2.1 Apache Lucene默认评分公式解释...
查看>>
《Adobe Premiere Pro CS4经典教程》——1.3 Adobe Premiere Pro CS4中的非线性编辑
查看>>
《VoIP技术构架(第2版·修订版)》一 第2章 企业电话的今天
查看>>
浏览器自动化测试解決方案 Geb
查看>>
《C程序员从校园到职场》一导读
查看>>
我希望一年前就知道 MongoDB 的那些事儿
查看>>
《Spark 官方文档》Spark独立模式
查看>>