Qt中的那些坑(二)---qDebug和QString中的轉義字符

【寫在前面】

qDebug 和 QString 算是Qt中最常用也最好用的工具了。

然鵝今天在使用它的時候,遇到了一些非常奇怪的問題。

結果實際上這個坑是 qDebug 導致,所以也不能全怪 QString。


【正文開始】

  • 首先,我們來看一段代碼:

#include <QCoreApplication>
#include <QDir>
#include <QDebug>
#include <iostream>

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    QString dir = app.applicationDirPath();
    dir = QDir::toNativeSeparators(dir);

    qDebug() << "qDebug:" << dir;
    std::cout << "cout:   " << dir.toStdString() << std::endl;
    printf("printf: ");
    for (auto ch : dir) {
        printf("%c", ch.toLatin1());
    }

    return app.exec();
}

猜猜看,這段代碼會輸出什麼?

如果你以爲三個輸出是一樣的,那麼恭喜你,你被坑了。

實際上,它們的輸出如下:

仔細觀察,coutprintf 是一樣的,唯獨 qDebug() 輸出了一些額外的東西。

我們來看文檔中 QDebug &QDebug::operator<<(const QString &t) 的描述:

Writes the string, t, to the stream and returns a reference to the stream. Normally, QDebug prints the string inside quotes and transforms non-printable characters to their Unicode values (\u1234).

To print non-printable characters without transformation, enable the noquote() functionality. Note that some QDebug backends might not be 8-bit clean.

翻譯:將字符串t寫入流,並返回對該流的引用。 通常,QDebug在引號中打印字符串,並將不可打印的字符轉換爲它們的Unicode值 (\u1234)。

要在不進行轉換的情況下打印不可打印的字符,請啓用 noquote() 功能。 請注意,某些QDebug後端可能不是8位乾淨的。

事實上,qDebug() 不僅會在引號中打印字符串、轉換 Unicode,還會完整打印轉義字符,例如:\\  \"  \t  \n 等等。

當然這樣做在很多時候是有好處的,畢竟爲了方便調試嘛( 調試利器 ),但在某些時候,也會讓你陷入坑裏。

  • 這樣可能導致什麼問題?

例如,某些時候你需要一個這樣的字符串( 當然這不常見 ):D:\\program\\FFMpeg\\test\\debug,於是你使用 qDebug() 打印一看,嗯?不錯,就是這個了。

然鵝實際上,它是 D:\program\FFMpeg\test\debug ,但你並不知曉,然後你接着用,這樣最後就可能引發一些的問題,並且還會埋怨 QString 是不是有毛病( 就像我一樣呵呵呵呵||ヽ(* ̄▽ ̄*)ノミ )。

  • 那麼,如何使用 qDebug() 輸出正確的字符串?

答案是 noquote()

#include <QCoreApplication>
#include <QDir>
#include <QDebug>
#include <iostream>

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    QString dir = app.applicationDirPath();
    dir = QDir::toNativeSeparators(dir);

    qDebug().noquote() << "qDebug:" << dir;
    std::cout << "cout:   " << dir.toStdString() << std::endl;
    printf("printf: ");
    for (auto ch : dir) {
        printf("%c", ch.toLatin1());
    }

    return app.exec();
}

結果如下:

文檔中 noquote() 的說明如下

Disables automatic insertion of quotation characters around QChar, QString and QByteArray contents and returns a reference to the stream.

When quoting is disabled, these types are printed without quotation characters and without escaping of non-printable characters.

翻譯:禁止在 QChar,QString 和 QByteArray 內容周圍自動插入引號字符,並返回對流的引用。

當禁用 quote 時,這些類型的打印將不帶引號字符,也不會轉義不可打印的字符。


【結語】

很多時候,我們確實享受着Qt帶來的各種便利。

但是偶爾,稍不留意,這些便利可能也會坑你一把。

所以,編程還需謹慎啊~ 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章