zoukankan      html  css  js  c++  java
  • QString够绕的,分为存储(编译器)和解码(运行期),还有VS编译器的自作主张,还有QT5的变化

    多读几篇,每篇取几句精华加深我对QString的理解。

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

    QString内部仍采用UTF-16存储数据且不会改变,但它读char*的时候(C++语言里最常见的形式,特别对于const来说是这样),默认按照latin1来解读字符串,这就造成乱码。

    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。

    一句话,读中文路径以及写入XML都容易,几乎什么都不用设置。唯独源代码里的中文要千万小心才能正确解析,如下:
    QTextCodec *ttt = QTextCodec::codecForName("GBK"); // 上面什么都不写,只写这句就已经够了。
    writer.writeTextElement("Chinese5",ttt->toUnicode("中国")); //

    参考:

    http://hi.baidu.com/dbzhang800/item/431f800fcb653e6dd55a1142
    http://www.360doc.com/content/12/0511/18/6828497_210377394.shtml

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

    • 万恶的MSVC?

    • 注意:如果你在使用msvc的编译器,除了前面提到的东西,你还需要知道一点:
      • 如果你的源码文件是带BOM的utf8,utf16等编码格式,它会有转码的动作。
      • 这样一来,tr()包住的字符串将转码成时GBK、BIG5等system编码,与源文件所用的编码不同。
      • 所以,对此,我们还需要指定源文件的编码:
      CODECFORTR = GB2312
      CODECFORSRC = UTF-8

    http://blog.csdn.net/dbzhang800/article/details/7325698
    http://blog.csdn.net/dbzhang800/article/details/7540905

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

    在Qt5中,这个问题终于不复存在了,因为

    这两个函数

    QTextCodec::setCodecForTr(...)
    QTextCodec::setCodecForCStrings(...)

    被直接去掉了。

    这样一来,受影响的直接是如下代码了:

    QString s1 = "我是中文";
    QString s2("我是中文");
    QString s3 = QObject::tr("我是中文")
    • 坏消息

    现在Qt5中尽管去掉了setCodecXXX这两个函数,但是默认编码还是latin1。如果你要想使用

    "我是中文"

    这样的字符串,必须自己使用QTextCodec或这QString::fromXXX 这种东西进行转换

    • 好消息 是:

    Qt5发布之时,默认将会是utf8编码,完全可以将你从Qt编码问题解放出来。

    • 坏消息,如果使用的是 MSVC2005/2008/2010,可能无法使用utf8编码,于是

    下面的代码

    QString s1 = "我是中文";
    QString s2("我是中文");
    QString s3 = QObject::tr("我是中文")

    将不会工作。

    • 因为从MSVC2005起,你无法给编译器设置字符串要使用的编码。尽管2003之前,也无法设置,但是它会遵循源码文件的编码。而2005就自作聪明了,即使你源码文件保存成不带BOM的utf8,它都会试图帮你转换一下。
    • 好消息是什么呢?

    如果你在Windows下,且使用的是MinGW,那么只要你将源码文件保存成utf8,前面的代码将直接可以工作(无须其他设置)

    如果你在其他平台了,那么应该都默认是utf8文件。同样无须进行设置。

    http://blog.csdn.net/dbzhang800/article/details/7325698

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

    没有了setCodecXXX的Qt5

    • 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

    http://blog.csdn.net/dbzhang800/article/details/7542672

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

    QtCreator对这个问题好像都是用转义编码来解决的:
    在控件上写入中文“退出”,然后查看其自动生成的.h文件中会发现对于非ascii字符都采用了转义编码,像这样
    actionExit->setText(QApplication::translate("MainWindow", "351200200345207272", 0));

    刚发完贴就找到方法了,可以用utf-8的16进制方式表示常量字符
    如果硬要在源码中使用非英文字符串的话,简单符合官方推荐的办法还是使用转义字符来描述了
    所以自己写了一个小工具方便的进行转换
    http://bbs.csdn.net/topics/390491128
    http://download.csdn.net/detail/aqtata/5596247
    将UTF-8字符串转换为Latin1编码,比如中文“你好”转换为“xE4xBDxA0xE5xA5xBD”

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

    源码必须是UTF-8,QString需要它
    在Qt5中,我们将把QString的8位(8-bit)成员函数的默认编码从Latin 1改为UTF-8。
    我建议使用QLatin1String来封装这些字符串,尤其是你正将它们用于一个有QLain1String重载的QString的函数。

    你要么用UTF-8重写你的代码,要么你需要用合适的QLatin1String或QTextCodec::toUnicode函数来封装这些字符串。我比较建议使用前一个选项:在你的源代码中使用UTF-8。

    http://blog.qt.digia.com/cn/2012/05/16/source-code-must-be-utf-8-and-qstring-wants-it/

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

    直接在代码中使用中文字符串,在Windows下无论用QCreator还是Visual Studio 都会出现中文字符串显示乱码问题
    原因是QString默认使用Ascii编码,要手动加入代码
    “QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale())”才能解决问题
    为什么Qt不默认就是使用QTextCodec::codecForLocale呢?这对各个国家都没有冲突啊

    呵呵,如果这样做,Qt岂不是知道倒退了10多年? 你提到这个是10多年前的做法吧,直接导致同一个程序无法跨平台了。在utf8盛行的时代,而VC6/7/8/9/…,默认采用locale字符集,也算是与时代有些格格不入了。
    http://qt-project.org/forums/viewthread/19144

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

    QT中的QString内容使用Unicode作为文本编码。但是实际系统中通常采用的是其他编码,例如GBK,utf8等。为了便于兼容这些格式,QT中还设置了两个字符串类型:
    QCString类: C类型字符串,必须以0结尾,也就是中间不能含有0. 例如GBK编码的字符串
    QByteArray类: 中间可以含有0.例如utf8编码的字符串

    注:通过测试,发现Delphi的String可以存储中间为0的字符串

    此外,为了对某些分块的字符串(例如从网络中获得的字符串片段)进行编码转换,QT还提供了一个QTextDecoder的辅助类,可以帮助对这类字符串进行解码。
    QTextCodec *codec = QTextCodec::codecForName("Shift-JIS");
    QTextDecoder *decoder = codec->makeDecoder();
    QString string;
    while (new_data_available()) {
    QByteArray chunk = get_new_data();
    string += decoder->toUnicode(chunk);
    }

    http://blog.sina.com.cn/s/blog_a401a1ea0101fh3z.html

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

    解决读取ini文件中中文乱码
    QSettings settings("xxxx.ini",QSettings::IniFormat);
    settings.setIniCodec(QTextCodec::codecForName("GB2312")); //在此添加设置,即可读写ini文件中的中文
    settings.beginGroup("company");

    解决读取中文文件中文的乱码
    QFile file("xxxx.txt");
    QTextStream stream(file,QIODevice::ReadOnly);
    stream.setCodeC( QTextCodec::codecForName("GB2312") );
    stream.readAll();

  • 相关阅读:
    如何退出Vi编辑状态
    iOS开发第三方工具——MBProgressHUD
    iOS开发第三方工具——AFNetworking
    iOS开发第三方工具——JSONKit
    iOS开发第三方工具——SSToolkit
    TestFlight工具的使用
    Block 的循环引用
    在 iOS 9 中使用 UIStackView 的总结
    说说视图层架构
    iOS开发技巧(2)
  • 原文地址:https://www.cnblogs.com/findumars/p/4011848.html
Copyright © 2011-2022 走看看