zoukankan      html  css  js  c++  java
  • QString中文乱码

    QString中文乱码

    
    
    
    处理方法:
    1. QString str = QString::fromLocal8Bit("中文"); // vs2008 vs2005
    2. QString str = QString::fromLocal8Bit("中文"); //  gcc vs2003, 如源码是 GBK 编码(记事本中的 ANSI 编码)
    3.QString str = QString::fromUtf8("中文");          //  gcc vs2003, 如源码是 UTF-8 编码
     
    在QT程序中, 如果直接用QString保存中文字符串,则会出现乱码,比如下面的程序
    输出不是 "中文" 两个字, 而是乱码:

    #include <QCoreApplication>
    #include <QString>
    #include <QDebug>
     
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        QString str("中文");
        qDebug() << str;
        return a.exec();
    }
    输出:
    QString中文乱码 - 栖 - 活着
     
    ===============================================================
     
    来看QString文档:
    QString str("中文"); 这句调用的QString构造数是下面这个, 只有这个和参数是匹配的:

    QString::QString ( const char * str )

    看介绍:
    Constructs a string initialized with the 8-bit string str. The given const char pointer is converted to Unicode using the fromAscii() function.
    使用一个8位的字符串来初使化一个QString.会调用fromAscii函数把这个字符串转化成Unicode字符串.
    即然fromAscii会把这个字符串转化成Unicode字符串,那为什么会出现乱码呢?
    来看看fromAscii的源码(源码可以在Qt安装目录下面的src目录下找到):
    QString QString::fromAscii(const char *str, int size)
    {
        return QString(fromAscii_helper(str, size), 0);
    }
     
    fromAscii会调用下面这个函数:
     
    QString::Data *QString::fromAscii_helper(const char *str, int size)
    {
    #ifndef QT_NO_TEXTCODEC
        if (codecForCStrings) {
            Data *d;
            if (!str) {
                d = &shared_null;
                d->ref.ref();
            } else if (size == 0 || (!*str && size < 0)) {
                d = &shared_empty;
                d->ref.ref();
            } else {
                if (size < 0)
                    size = qstrlen(str);
                QString s = codecForCStrings->toUnicode(str, size); // 关键是这句
                d = s.d;
                d->ref.ref();
            }
            return d;
        }
    #endif
        return fromLatin1_helper(str, size);
    }
     
    从红色的那句可以知道, fromAscii最终是通过 codecForCStrings 把字符串转换成QString的在qstring.h
    头文件中可以看到如下的定义:
    #ifndef QT_NO_TEXTCODEC
        static QTextCodec *codecForCStrings;
    #endif
    现在知道字符串是通过一个QTextCodec对象来转换成一个字符串的.看toUnicode的定义:

    QString QTextCodec::toUnicode ( const Char * a , int size, ConverterState * state = 0 ) const

    Converts a from the encoding of this codec to Unicode, and returns the result in a QString.

    把字符串a从codecForCStrings所表示的编码转换到Unicode编码.

    前面写的 str("中文"); 出现的乱码, 很有可能是因为codecForCStrings所表示的编码不对.在QTextCodeC中有这样一个函数:

    void setCodecForCStrings ( QTextCodec * codec )

    这是一个静态函数看它的实现代码, 在文件qtextcodec.h中:

    inline void QTextCodec::setCodecForCStrings(QTextCodec *c) { QString::codecForCStrings = c; }

    只有一句话, 就是设置codecForCStrings的值, 这就是用于把 char * 转换成Unicode的对象.

    我们来试试重新设置一下 codecForCStrings 对象,修改一下它所表示的编码, 下面是修改后的代码:

    
    
    
    
    
    
    
    
    

    #include <QCoreApplication>

    #include <QString>

    #include <QDebug>

    #include <QTextCodec>

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

    {

        QCoreApplication a(argc, argv);

        QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK")); // 关键是这句

        QString str("乱码");

        qDebug() << str;

        return a.exec();

    }


    编译运行看结果:
    QString中文乱码 - 栖 - 活着

    正如期待的一样, 可以正确的显示中文.

    那么为什么加上那句就可以正确显示中文了呢?

     QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK")); // 关键是这句

    加这句是认为字符串 "乱码" 是GBK编码的.结果非常的 "巧合" 它正好是GBK编码的.所以结果就正确了.

    为什么设为GBK编码就可以了呢?? 

    因为我用的是 Visual Studio 2008 编译的, vs2008 编译器编译时会把 字符串 用locale字符编码字符串

    我的系统编码是GBK, 所以就正确了.

    至于其它的编译器, 请参考链接中的文章...大牛写的.

    
    
    

    vs2008, vs2005.编译时不管源码是什么编码都会把源码中的字符串转换成 locale 编码(中文系统就是GBK),

                          有两种方法处理中文:

                          1. QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK")); // 关键是这句

                      2.QString str = QString::fromLocal8bit("中文");

    
    

    vs2003,    1. 如果源码是 ANSI(中文系统中的GBK编码) 编码的, 则在程序中可以这样处理中文:

                              QString str = QString::fromLocal8bit("中文");

                    2. 如果源码是 UTF-8 编码的则在程序中可以这样处理中文:

                              QString str = QString::fromUtf8("中文");

    gcc 和 vs2003一样的处理, 不过gcc有编译选项可以设置, 请参数后面的链接.


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

    QString 乱谈

     QtInternal 之 高效使用QString

    我发现在数组里必须要这样写:

    FROM: http://tgstdj.blog.163.com/blog/static/748200402013213105251450/

  • 相关阅读:
    Java实现 LeetCode 382 链表随机节点
    Java实现 LeetCode 382 链表随机节点
    Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素
    Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素
    Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素
    Java实现 LeetCode 380 常数时间插入、删除和获取随机元素
    Java实现 LeetCode 380 常数时间插入、删除和获取随机元素
    Linux下的iwpriv(iwlist、iwconfig)的简单应用
    OCX控件的注册卸载,以及判断是否注册
    .OCX、.dll文件注册命令Regsvr32的使用
  • 原文地址:https://www.cnblogs.com/sggggr/p/13456833.html
Copyright © 2011-2022 走看看