为什么QString打印时带有引号?

25

因此,当你使用qDebug()打印QString时,输出中会突然出现引号。

int main()
{
    QString str = "hello world"; //Classic
    qDebug() << str; //Output: "hello world"
    //Expected Ouput: hello world
}

我知道我们可以使用qPrintable(const QString)解决这个问题,但我只是想知道为什么QString会像那样工作?是否有一种方法可以在QString内部更改打印方式?


可能是如何在不添加空格和换行符的情况下调用qDebug?的重复问题。 - Michael Petch
5个回答

42

Qt 5.4有一个新功能,可以让你禁用这个特性。引用文档的话:

QDebug&QDebug :: noquote()

禁止自动插入引号字符到QChar,QString和QByteArray内容中,并返回流的引用。

此函数在Qt 5.4中引入。

另请参阅quote()和maybeQuote()。

(强调是我加的。)

以下是如何使用此功能的示例:

QDebug debug = qDebug();
debug << QString("This string is quoted") << endl;
debug.noquote();
debug << QString("This string is not") << endl;

另一个选择是使用QTextStreamstdout一起使用。 在文档中有一个示例:

QTextStream out(stdout);
out << "Qt rocks!" << endl;

很有用的信息,谢谢。但是在编译时,我发现在Linux版本的Qt中,QDebug::noquote()未被定义为QDebug的成员。可能是因为它只基于Qt 5.4。 - Michael
@Michael,我添加了一个示例,请看看是否有帮助。 - MrEricSir
5
我正在使用 qDebug().noquote() << QStringRef(back, i, cols);... 我认为它是一样的,我也尝试了你的示例,但我一直收到错误提示说 noquote() 不是 QDebug 的成员,谢谢你的帮助,但这可能是因为我的 Qt 版本问题。我的 Linux 版本实际上不是 5.4,只是基于 5.4,也许这就是原因。 - Michael
这确实有效,在某些情况下可能会有所帮助,但有一个重大缺点:调试输出(至少在我的系统上)直到QDebug对象被销毁才会被打印出来,因此在应用程序关闭之前可能无法获取调试输出(在这一点上,它在技术上不再是调试/日志输出...)。 - ssc
为什么我们需要使用 endl 呢? - Martin Delille

16

为什么?

这是因为实现了qDebug()

源代码可以看到:

inline QDebug &operator<<(QChar t) { stream->ts << '\'' << t << '\''; return maybeSpace(); }
inline QDebug &operator<<(const char* t) { stream->ts << QString::fromAscii(t); return maybeSpace(); }
inline QDebug &operator<<(const QString & t) { stream->ts << '\"' << t  << '\"'; return maybeSpace(); }

因此,
QChar a = 'H';
char b = 'H';
QString c = "Hello";

qDebug()<<a;
qDebug()<<b;
qDebug()<<c;

输出

'H' 
 H 
"Hello"

评论

那么Qt为什么要这样做呢?因为qDebug是用于调试的,各种类型的输入将通过qDebug变成文本流输出。

例如,qDebug会将布尔值打印为文本表达式true/false

inline QDebug &operator<<(bool t) { stream->ts << (t ? "true" : "false"); return maybeSpace(); }

它会在您的终端输出truefalse。因此,如果您有一个存储trueQString,您需要使用引号"来指定类型。


1
所以这就是为什么qPrintable(const QString)会移除引号的原因。非常感谢。 - Michael
@Michael 不是的,我认为只是一些美学问题。qDebug只是想强调类型之间的差异,所以它使用"友好地提醒您QString的类型。毕竟,这是为了调试而不是打印。 - Tay2510
是的,但 qPrintable 返回一个 const char,根据您提供的源代码,当将 const char 作为参数传递给 << 运算符 QDebug 不会附加引号。如果我错了,请纠正我。 - Michael
1
@Michael 你说得对。您还可以参考MrEricSir的答案来删除引号,并查看我的最后一次编辑以了解背后的动机。 - Tay2510
那不是一个“因为”的理由,无论如何。最重要的“因为”是要在您的字符串中检测前导/尾随空格! - peppe

6

Qt 4:如果字符串只包含ASCII字符,则可以采用以下解决方法:

qDebug() << QString("TEST").toLatin1().data();

3
这实际上是解决 https://bugreports.qt.io/browse/QTBUG-48517 的有效方法。在 Qt5 中,.data()将会像在 Qt4 中一样打印 String 的内容。我相信它因为不必要的 toLatin1 而被贬低,但这可以改成 toUtf8 等。 - tresf

2

只需将其转换为const char *

qDebug() << (const char *)yourQString.toStdString().c_str();

1
Qt 包含了一个函数,基本上可以实现这个功能:const char * qPrintable ( const QString & str ) - btse
1
文档中提到,当使用qDebug时,应该使用qUtf8Printable,因为qDebug期望的是UTF-8编码。 - José Tomás Tocino

1

一行代码无引号:qDebug().noquote() << QString("string");


1
这并没有提供问题的答案。如果要批评或请求作者澄清,请在他们的帖子下留言。-【来自审查】 - ankita patel
在QString内部是否有一种方法可以改变其打印方式?用一行话回答。 没有特定的QString方法来更改其打印方式。 - GO.exe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接