我试图避免QT程序中的混合QString和char*类型。我有一个会话函数,它返回QString内部数据的指针,但是我得到了非常奇怪的结果。这个密码有什么问题吗?
编译器和环境gcc (Debian4.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!发布于 2016-12-05 20:53:06
在这里,您要将QString复制到函数,并返回指向函数中已经销毁的数据的指针。这是已知的未定义行为,因为您正在返回指向垃圾的指针。返回QString。
const char* CH(QString msg) {
const char* res = msg.toAscii().data();
return res;
}发布于 2016-12-05 21:09:42
您应该使用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,而不是创建了一个8位C-字符串.它在编译时组装QString,并将其存储在可执行文件的只读内存部分。这是避免字符串编码运行时成本的唯一方法。
如果已经有QString编码的字符串文本或UTF8编码的C风格字符串,则通过UTF8进行往返没有任何好处。如果您需要使用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());
}https://stackoverflow.com/questions/40982784
复制相似问题