使用QString類進行編碼轉換

2020-07-16 10:05:03
QString 類包含了大量關於文字字串編碼轉換的函數,涉及之前提到的 UTF-8、UTF-16、UTF-32、本地語言編碼 Local8Bit,還有標準 C++ 的普通字串 StdString 和寬字串 StdWString,對於其他編碼轉為 QString,採用的是 QString::from* 靜態公有成員函數,這些靜態函數返回一個轉換好的 QString 物件以供使用。與之對應的是 QString 類物件的 to* 函數,QString 物件可以呼叫這些 to* 函數轉出為其他編碼格式的字串。

下面將 QString 類這些成對的函數列一個表,方便查閱:
轉入函數 轉出函數 描述
fromLocal8Bit toLocal8Bit 與作業系統及在地化語言相關,Linux 一般是 UTF-8 字串,Windows 一般是 ANSI 多位元組編碼字串。
fromUtf8 toUtf8 與 UTF-8 編碼的字串相互轉換。
fromUtf16 utf16 和
unicode
與 UTF-16(UCS2)編碼的字串互相轉換,utf16 函數與 unicode 函數功能一樣, 注意沒有 to 字首,因為 QString 執行時的內碼就是 UTF-16,字元的雙位元組採用主機位元組序。
fromUcs4 toUcs4 與 UTF-32(UCS4)編碼的字串互相轉換,一個字元用四個位元組編碼,佔空間多,應用較少。
fromStdString toStdString 與 std::string 物件互相轉換,因為 C++11 規定標準字串 std::string 使用 UTF-8 編碼,這對函數功能與上面 **Utf8 轉碼函數相同。
fromStdWString toStdWString 與 std::wstring 物件相互轉換,在 Linux 系統裡寬字元是四位元組的 UTF-32,在 Windows 系統裡寬字元是兩位元組的 UTF-16。因為不同平台有歧義,不建議使用。
fromCFString
fromNSString
toCFString
toNSString
僅存在於蘋果 Mac OS X 和 iOS 系統。

下面展示一個 qtcodec 例子,裡面主要使用 QString 物件的轉出函數,然後使用 cout 或 qDebug 列印相應的輸出。請「猛擊這裡」下載原始碼。

下載後解壓到比如 D:QtDemoqtcodec 資料夾,然後用 QtCreator 開啟該專案,專案設定和上節示範的一樣。 然後開啟 qtcodec.cpp 檔案,檢視裡面的內容: 
//qtcodec.cpp
#include <QApplication>
#include <QTextBrowser>
#include <QDebug>
#include <iostream>
using namespace std;

void Testcout(const QString &str)
{
    //Locale charset
    cout<<str.toLocal8Bit().data()<<endl;

    //UTF-8
    cout<<str.toUtf8().data()<<endl;
    cout<<str.toStdString()<<endl;

    //UTF-16, Windows Unicode, UCS2
    cout<<str.unicode()<<endl;
    cout<<str.utf16()<<endl;
    cout<<str.data()<<endl;

    //UTF-32, UCS4
    cout<<str.toUcs4().data()<<endl;

    //wchar_t: Windows = UTF-16; Linux/Unix = UTF-32
    wcout<<str.toStdWString();

    cout<<endl<<endl;
}

void TestqDebug(const QString &str)
{
    //Locale charset
    qDebug()<<str.toLocal8Bit().data();

    //UTF-8
    qDebug()<<str.toUtf8().data();
    qDebug()<<str.toStdString().data();

    //UTF-16, Windows Unicode, UCS2
    qDebug()<<str.unicode();
    qDebug()<<str.utf16();
    qDebug()<<str.data();

    //UTF-32, UCS4
    qDebug()<<str.toUcs4().data();

    //wchar_t: Windows = UTF-16; Linux/Unix = UTF-32
    qDebug()<<str.toStdWString().data();

    //QString object
    qDebug()<<str;
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QString strText = QObject::tr("1234列印漢字");
    QTextBrowser tb;
    tb.setText(strText);
    tb.setGeometry(40, 40, 400, 300);
    tb.show();
    //Test cout
    Testcout(strText);
    //Test qDebug
    //TestqDebug(strText);

    return a.exec();
}
qtcodec.cpp 裡面首先是標頭檔案包含和命名空間使用,然後是三個函數:Testcout、TestqDebug 和 main 函數。Testcout 和 TestqDebug 函數裡的內容參看上面表格,就不一一解釋了。

需要注意一條,QString 類物件可以通過 data 函數返回它實際的資料儲存塊指標,如 str.data(),在後面執行測試時可以看到該指標數值。

注意兩個測試函數不要同時啟用,一次測試一個,另一個注釋掉,這樣檢視它們執行結果更清楚,而不會混淆。

先測試 Testcout 函數執行效果: