Qt 中文字符串问题

一.linux

Qt5假定的执行字符集是UTF8,再也不容许用户擅自改动。这样一来,Qt4中setCodecXXX的各类反作用再也不存在,并且中文问题更为简单。函数

 

QString s1 = "汉语";
QString s2("漢語"); QString s3 = tr("中文") QString s4 = QStringLiteral("中文");//只要字符串不须要翻译,请关注这个 QString s5 = QString::fromWCharArray(L"中文"); QString s6 = u8"中文";//C++11 QString s7 = tr(u8"中文") ...

全部这些在Qt5默认都会正常工做,惟一要求就是:确保你的C++的执行字符集(the execution character set)是UTF-8编码

 

被误用最多的:此种方法解析结果是错误的spa

在Qt4中,QObject::tr()是被滥用(误用)的函数之一:.net

QString s3 = tr("中文")
...

缘由:翻译

  • 在Qt4,很多用户被铺天盖地的setCodecForTr()所影响,进而靠它来解决中文问题。

它的用途是用来进行翻译(I18N和L10N)的,若是你没有这方面的需求,真的不必用它。(在Qt4中,我只注意到有2个大陆网友和1个日本网友有需求并真正进行过这方面的尝试,那么其余应该算误用吧?)code

 

让人困惑的wchar_tblog

刚开始接触Qt和QString时,曾屡次想过,为何不用wchar_t,为何,...unicode

QString s5 = QString::fromWCharArray(L"中文");

这个东西在Windows下真的颇有用:首先它是Windows系统API所用字符串,其次它和QString内部表示相同。可是因为MSVC处于种种考虑,鼓励你们使用TEXT/_T,反倒使你们对它比较陌生。字符串

可是从C++标准来讲,wchar_t毕竟不是char16_t,因此跨平台性很差。在linux下,这行代码须要utf32到utf16的转换。

QStringLiteral

这是一个宏,一个蛮复杂的宏:

QString s4 = QStringLiteral("中文");

以前?

在介绍这个宏以前,咱们先看看下面写法有什么劣势:

QString s1 = "汉语";
QString s2("漢語"); QString s3 = tr("中文") QString s6 = u8"中文";//C++11 ...

首先,2个汉字的字符串以UTF-8编码的形式被编译器放到了常量区。(至少占7个字节吧?)

而后,程序运行时,构造QString实例,须要在堆上申请空间,存放utf16格式的相应字符串。

有没有存在浪费?

方案

QString 内部是UTF16,若是C++编译器在编译期直接提供了UTF16的字符串,那么咱们在QString内部直接保存也就够了。这样

  • 省掉存在两份不一样的拷贝(即相应的转换,malloc的成本)
  • 对汉字来讲,UTF16自己就是UTF8省空间

现实

目前,咱们尚未可靠的方式在C++使用UTF16的执行字符集(the execution character set)。

  • 尽管 L"..."(wchar_t*) 在Windows下是UTF16,可是不具有跨平台性。
  • C++11能够保证这一点,u"..."(char16_t),但主流编译器还没有提供完美支持。

这两点,致使了QStringLiteral的复杂性

实现

源码见 qtbase/src/corelib/tools/qstring.h

(代码中使用宏、模板、lambda表达式,仍是至关复杂的,此处只摘片断)

  • 若是编译器支持char16_t,则直接使用

 

#define QT_UNICODE_LITERAL_II(str) u"" str
typedef char16_t qunicodechar; ...
  • 不然。若是在Windows平台下,或者在其余的wchar_t宽度为2的环境下,使用wchar_t

 

#if defined(Q_CC_MSVC)
# define QT_UNICODE_LITERAL_II(str) L##str #else # define QT_UNICODE_LITERAL_II(str) L"" str #endif typedef wchar_t qunicodechar; ...
  • 不然。编译器不支持,Qt做为一个库,确定也没有办法

 

# define QStringLiteral(str) QString::fromUtf8(str, sizeof(str) - 1)
相关文章
相关标签/搜索