ChatGPT解决这个技术问题 Extra ChatGPT

QString 到 char* 的转换

我试图通过以下方法将 QString 转换为 char* 类型,但它们似乎不起作用。

//QLineEdit *line=new QLineEdit();{just to describe what is line here}

QString temp=line->text();
char *str=(char *)malloc(10);
QByteArray ba=temp.toLatin1();
strcpy(str,ba.data());

您能否详细说明这种方法可能存在的缺陷,或者提供一种替代方法?

你的例子对我来说很好,问题出在哪里?
对不起我的英语,但为什么使用这种方法是不对的? QString s("some"); printf(reinterpret_cast<char *>(s.data()));

b
bur

好吧,Qt FAQ 说:

int main(int argc, char **argv)
{
 QApplication app(argc, argv);
  QString str1 = "Test";
  QByteArray ba = str1.toLocal8Bit();
  const char *c_str2 = ba.data();
  printf("str2: %s", c_str2);
  return app.exec();
}

所以也许你还有其他问题。这到底是怎么回事?


const char*char* 不是同一类型。
@LightnessRacesinOrbit:在不知道的情况下写入 QString 的内容是一个可怕的想法,因此当然 const char* 是真正可以获得的。用户可以自由地将数据复制到可写缓冲区。
我完全同意。但是,问题是关于 char* 而不是 char const*,您的回答只是忽略了这个事实而没有提及。
@LightnessRacesinOrbit:有时最好的答案是不要问这个问题。换句话说,要指出这不是在问正确的事情。这个答案被问题发布者接受了,所以我想它达到了目标
似乎常见问题解答已更新为使用 toLocal8Bit()
d
davidnr

也许

my_qstring.toStdString().c_str();

或者更安全,正如 Federico 指出的那样:

std::string str = my_qstring.toStdString();
const char* p = str.c_str();

它远非最佳,但会完成工作。


这会弄乱 Unicode 字符。 Unicode 友好的解决方案:stackoverflow.com/a/4644922/238387
这种方法非常危险,不应该使用:toStdString() 返回一个新的 std::string 对象,然后获得指向内部数据 const char * 的指针。但是,该字符串对象在此语句之后立即被销毁,因此如果您在后续语句中使用它,结果指针可能没有有效地址。
@RicoRico 危险的不是方法 toStdString();这是使用原始指针。或者,更具体地说,使用来自其作用域还没有被很好理解的对象的原始指针。
具体来说,C++ 临时对象通常会持续到创建它们的语句结束。因此,如果它在函数调用中内联使用(假设函数不存储指针以供将来使用),则答案中的第一种形式是可以的,但如果将其分配给变量则不行。
正如@plugwash 所说,从临时生命周期的角度来看,f(qstr.toStdString().c_str()) 是可以的(延长到 f 结束)。但是,从 C++17 开始,a.b 的评估顺序仅保证在 b 之前是 a。我想大多数实现在实践中已经可以这样工作了,但严格来说我相信它会是 C++17 之前的 UB
K
KernelPanic

QString 转换为 char* 的最简单方法是 qPrintable(const QString& str),它是扩展为 str.toLocal8Bit().constData() 的宏。


为什么这不是一个更受欢迎的答案?我只是在浏览 Qt 源代码时偶然了解到这一点,而这正是他们所做的。
@Phlucious,因为:1) qPrintable 返回 const char* 而不是 char*str.toLocal8Bit().data() 返回 char*。 2) 一旦您在使用 qPrintable 的语句中点击分号,指向 const char* 的指针就会变为无效。所以 const char* c_ptr = s.toLocal8Bit().constData(); 没有任何意义。
@Phlucious 谢谢你是救命稻草 :) 这些所有投票最多的答案都是错误的,问题是关于 char 的,他们正在返回 const char*
qPrintable 输出是否保证为零终止?
@WindyFields - 正如 qPrintable() 描述中警告的那样:“在使用 qPrintable() 的语句之后,char 指针将无效。”
A
Alex

如果您仅将 David 的答案用于输出到文件或在屏幕上显示,那么 David 的答案可以正常工作,但如果函数或库需要 char* 进行解析,则此方法效果最佳:

// copy QString to char*
QString filename = "C:\dev\file.xml";
char* cstr;
string fname = filename.toStdString();
cstr = new char [fname.size()+1];
strcpy( cstr, fname.c_str() );

// function that requires a char* parameter
parseXML(cstr);

J
Jorge Luis

已编辑

这种方式也有效

QString str ("Something");

char* ch = str.toStdString().C_str();

这看起来像是不同的转换(std::stringQString),而不是要求的。
g
gregseth

您的字符串可能包含非 Latin1 字符,这会导致未定义的数据。这取决于您所说的“它似乎不起作用”的意思。


A
AlexDarkVoid

如果您的字符串包含非 ASCII 字符 - 最好这样做:s.toUtf8().data()(或 s->toUtf8().data()


s
sam

正确的解决方案是这样的

   QString k;
   k = "CRAZYYYQT";
   char ab[16];
   sprintf(ab,"%s",(const char *)((QByteArray)(k.toLatin1()).data()) );
   sprintf(ab,"%s",(const char *)((QByteArray)(k.toStdString()).data()));  
   sprintf(ab,"%s",(const char *)k.toStdString().c_str()  );
   qDebug()<<"--->"<<ab<<"<---";

忘记使用 C 风格的转换。
J
JBES

Qt 提供了最简单的 API

const char *qPrintable(const QString &str)
const char *qUtf8Printable(const QString &str)

如果您想要非常量数据指针,请使用

str.toLocal8Bit().data()
str.toUtf8().data()

T
TCH

使用 std::vector 作为中间容器是一种可行的方法:

QString dataSrc("FooBar");
QString databa = dataSrc.toUtf8();
std::vector<char> data(databa.begin(), databa.end());
char* pDataChar = data.data();