构建 QString 输出字符串

Building QString out string

用下面的一段代码:

QString msg;
msg =   "Datalogging Item"          + ',' +
        QString::number(item)       + ',' +
        "Slave Index"               + ',' +
        QString::number(slaveIndex) + ',' +
        "Slave Name"                + ',' +
        slaveName                   + ',' +
        "Experiment Index"          + ',' +
        QString::number(expIndex)   + ',' +
        "Experiment Name"           + ',' +
        expName                     + ',' +
        "Aquisition Frequency "     + ',' +
        "33 Hz"                     + "\n";
qDebug() << msg;

我得到以下调试输出

"riment Index0,Slave Index,0,Slave Name,Execute 1,Experiment Index,0,Experiment Name,Read All (Barebone),Aquisition Frequency ,33 Hz\n"

这不是我期望得到的。

但是使用 QString 类型转换修改代码:

QString msg;
msg =   QString("Datalogging Item")     + QString(',') +
        QString::number(item)           + QString(',') +
        QString("Slave Index")          + QString(',') +
        QString::number(slaveIndex)     + QString(',') +
        QString("Slave Name")           + QString(',') +
        slaveName                       + QString(',') +
        QString("Experiment Index")     + QString(',') +
        QString::number(expIndex)       + QString(',') +
        QString("Experiment Name")      + QString(',') +
        expName                         + QString(',') +
        QString("Aquisition Frequency ")+ QString(',') +
        QString("33 Hz")                + QString("\n");
qDebug() << msg;

我得到了我期望得到的:

"Datalogging Item,0,Slave Index,0,Slave Name,Execute 1,Experiment Index,0,Experiment Name,Read All (Barebone),Aquisition Frequency ,33 Hz\n"

你知道发生了什么事吗?我只是不明白发生了什么,而且我是 QT 的新手。

谢谢。

您可以更简单地重现相似结果:

 msg =   "Datalogging Item" + ',' +  QString::number(item);

现在恰好是问题所在。该表达式的第一部分很简单:

"Datalogging Item" + ','

在上面的表达式中,原始字符串文字将整数值 44(逗号的 ascii val)添加到它的指针地址。因此,由于 "Datalogging Item" 的长度远小于 44 个字符,您现在处于 "undefined" 区域。最有可能发生的事情是上面的表达式现在是指向附近定义的其他字符串文字之一的中间的指针表达式。

解决方案是简单地将第一个元素声明为QString,以便所有后续"additions"将使用QString的重载+运算符:

msg =   QString("Datalogging Item") + ',' +
        QString::number(item)       + ',' +
        ...

代码中静态字符串最好使用QStringLiteral宏

msg = QStringLiteral("Datalogging Item") + ',' +

更多信息在这里:http://doc.qt.io/qt-5/qstring.html#QStringLiteral

表达式

"Datalogging Item" + ','

具有

的类型和含义
static_cast<const char *>("Datalogging Item" + 44)

您正在获取 Datalogging 字符串常量的开头地址并向其添加 44 - 将其向前推进 44 个字符。当您将指针移过它指向的对象时,这是未定义的行为。巧合的是,指针恰好指向另一个 C 字符串常量。

重现问题的短程序:

#include <iostream>
int main() {
  std::cout << "Datalogging Item Foo Bar Baz" + '\n' << std::endl;
}

输出:

g Item Foo Bar Baz

重写表达式以使其有效且不那么冗长的一种方法是使用 QString:

的 arg 替换机制
auto msg = QStringLiteral(
  "Datalogging Item,%1,Slave Index,%2,Slave Name,%3,Experiment Index,%4,"
  "Experiment Name,%5,Acquisition Frequency,%6\n")
   .arg(item).arg(slaveIndex).arg(slaveName).arg(expIndex)
   .arg(expName).arg(QStringLiteral("33 Hz"));

如果您使用的是 Qt 4,请将 QStringLiteral 替换为 QString::fromUtf8QStringLiteral 是 Qt 5 中引入的一种机制,它在编译时构建一个常量 QString 实例,比使用 QString 构造函数产生更小的代码和更好的运行时性能。