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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM