QString格式将无法使用QDebug

QString formatting will not work qDebug

本文关键字:QDebug 格式 QString      更新时间:2023-10-16

我尝试避免使用QT程序中的QStringchar*类型。我有一个会话功能,该功能返回QString内的数据指针,但是结果我会得到非常奇怪的结果。此代码怎么了?

编译器和环境GCC(Debian 4.9.2-10)4.9.2通过QMAKE的标志:QMAKE_CXXFLAGS += -std=c++11

代码段:

#include <QCoreApplication>
#include <iostream>
#define  PCH(m) ( m.toAscii().data() )
// get the pointer short scripted
const char* CH(QString msg) {
   const char* res = msg.toAscii().data();
   return res;
}
int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    const QString qformat = "%s does not work!";
    const QString qvalue  = "embedding";
    // Works not
    qDebug(CH(qformat), CH(qvalue));   
    // Works
    qDebug(qformat.toAscii().data(), qvalue.toAscii().data());
    // Works too but macro
    qDebug(PCH(qformat), PCH(qvalue));   
    return app.exec();
}

结果

%s does not work! does not work!
embedding does not work!
embedding does not work!

在这里,您将QString复制到功能,然后将指针返回到函数内已经破坏的数据。这是已知的未定义行为,因为您将指针返回垃圾。返回QString。

const char* CH(QString msg) {
    const char* res = msg.toAscii().data();
    return res;
}

您应该使用qDebug()QString本身内置的格式机制。您还应该使用QStringLiteral而不是依赖默认字符串转换 - 毕竟您说明您关心这样的事情:

#include <QtCore>
int main()
{
    const auto qformat = QStringLiteral("%1 does work!");
    const auto qvalue = QStringLiteral("embedding");
    qDebug() << qformat.arg(qvalue);
    qDebug() << qformat.arg(0x7A01173C2, 0, 16);
}

在现代编译器上使用的QStringLiteral not 创建一个8位C弦。它在编译时组装了QString的二进制内部表示形式,并将其存储在可执行文件的只读内存部分中。这是避免字符串编码的运行时成本的唯一方法。

如果您已经拥有编码UTF8编码的UTF8编码字符串文字或C风格字符串,则通过QString进行往返都没有任何好处。如果您需要使用C风格的字符串/字符串文字,请与qDebug直接使用它们:

#include <QtCore>
int main() {
    const char format[] = "%s does not work!";
    const char value[] = "embedding";
    qDebug(format, value);
}

如果您需要通过临时的C风格字符串,请使用QByteArray,但这确实是很多代码,几乎没有什么可显示的 - 详细说明很详细,以至于具有非常糟糕的代码气味。所以不要这样这样做:

#include <QtCore>
QByteArray CH(const QString &msg) {
   return msg.toLocal8Bit();
}
int main()
{
    auto qformat = QStringLiteral("%s does work!");
    auto qvalue = QStringLiteral("embedding");
    qDebug(CH(qformat).constData(), CH(qvalue).constData());
}