QString转换为char *


94

我试图通过以下方法将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());

您能否详细说明此方法可能存在的缺陷,或给出替代方法?


您的示例对我来说效果很好,问题出在哪里?
维斯特(Viesturs)2010年

3
对不起,我的英语,但是为什么使用这种方法不合适? QString s("some"); printf(reinterpret_cast<char *>(s.data()));
bartolo-otrit 2012年

Answers:


114

好吧,Qt常见问题解答说:

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();
}

因此,也许您还有其他问题。这到底是怎么工作的?


11
const char*并且char*不是同一类型。
Lightness Races in Orbit

3
@LightnessRacesinOrbit:在不知道QString内容的情况下写它是一个可怕的想法,因此当然const char*可以真正获得。用户可以自由地将数据复制到可写缓冲区。
Eli Bendersky

1
我完全同意。但是,询问的问题char*不是char const*,而您的回答只是忽略了这一事实而没有提及。
Lightness Races in Orbit

4
@LightnessRacesinOrbit:有时最好的答案是不要提出这个问题。换句话说,要指出这并不是在问正确的事情。问题发布者接受了这个答案,因此我想它达到了目标
Eli Bendersky 2012年

2
似乎FAQ已更新为可使用toLocal8Bit()
拉里

52

也许

my_qstring.toStdString().c_str();

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

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

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


3
这会弄乱Unicode字符。一种Unicode友好的解决方案:stackoverflow.com/a/4644922/238387
jlstrecker 2012年

21
此方法非常危险,不应使用:toStdString()返回一个新std::string对象,然后获取指向内部数据的指针const char *。但是,该字符串对象在此语句后立即被销毁,因此,如果在后续语句中使用该结果,则结果指针可能没有有效的地址。
RicoRico

@RicoRico这不是toStdString()危险的方法;这是原始指针的使用。或者,更具体地说,使用对象的原始指针,这些对象的作用域没有被很好地理解。
notlesh

具体来说,C ++临时成员通常一直存在到创建它们的语句结束为止。因此,如果在函数调用中内联使用它,则答案中的第一种形式是可以的(假设该函数未存储指针供将来使用),但如果将其分配给变量,则不是可以的。
Plugwash

46

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


为什么这不是更受欢迎的答案?我只是在戳Qt源时偶然地了解了这一点,而这正是他们所做的。
富饶的2016年

6
@Phlucious,因为:1)qPrintable返回const char*char*str.toLocal8Bit().data()回报char*。2)const char*一旦您在qPrintable所使用的语句中打了分号,指向的指针就会失效。因此const char* c_ptr = s.toLocal8Bit().constData();没有任何意义。
WindyFields

1
@Phlucious,谢谢,您是救命的人:)所有这些投票最多的答案都是错误的,问题是关于char的,他们正在返回const char *
user889030

是否qPrintable保证输出端接零?
Giovanni Cerretani

@WindyFields-如qPrintable()描述中所警告:“在使用qPrintable()的语句之后,char指针将无效。”
杰里米

6

如果仅将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);

4

已编辑

这种方式也可以

QString str ("Something");

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

这看起来像是一个不同的转换(std::stringQString),而不是要求的转换。
Toby Speight

3

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


2

正确的解决方案将是这样的

   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样式转换。
kyb


0

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

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

0

Qt提供最简单的API

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

如果要使用非常量数据指针

str.toLocal8Bit().data() or str.toUtf8().data()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.