【寫在前面】
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();
}
猜猜看,這段代碼會輸出什麼?
如果你以爲三個輸出是一樣的,那麼恭喜你,你被坑了。
實際上,它們的輸出如下:
仔細觀察,cout 和 printf 是一樣的,唯獨 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帶來的各種便利。
但是偶爾,稍不留意,這些便利可能也會坑你一把。
所以,編程還需謹慎啊~