Pure way to convert QString to char * (not const char * !!!!)

I have an ugly code for this stuff (create a c char pointer and copy the QString in it), but maybe ... exist in QT in an elegant way ...

valid code:

QString maquina is a method parameter. char *c_maquina = new char[maquina.length() + 1]; strcpy(c_maquina, maquina.toStdString().c_str()); 

for information only I need a REAL char * not a simple const char *, so this code does not work:

 idMaquina.toLatin1().data(); 

I can not use http://developer.qt.nokia.com/faq/answer/how_can_i_convert_a_qstring_to_char_and_vice_versa

+7
c ++ qt
source share
7 answers

It's simple:

 QByteArray array = string.toLocal8Bit(); char* buffer = array.data(); 

You can also use toLatin1 or toUtf8 instead of toLocal8Bit . Please note: none of them can be queued with a call to data . And toStdString().c_str() also invalid. This is due to the fact that any QByteArray or std::string created in this way is temporary and will be destroyed immediately by destroying the char buffer. You need to store the QByteArray in a local variable while you use the buffer.

Also note that Qt provides the QByteArray class for working with char arrays. As a rule, there is no need to use char* , you can do almost everything with QByteArray .

+26
source share

I think the decision depends on the type of characters that need to be converted, and whether to integrate / call the C-style function with arguments of type "char *".

  • If a C-style function needs to be integrated / called, do not use toStdString (), followed by c_str (), since the return type is "const char *", which is not suitable for the C-style function.
  • Use toLatin1 () followed by data () for ASCII characters.
  • Use toLocal8Bit () or toUtf8 () followed by data () for other UTF8 characters than ASCII.

If several solutions can be used for your particular case, their performance levels may differ slightly, which I have not tested.

The following test program shows how to use these solutions:

 #include <QCoreApplication> #include <QDebug> // This is a C-style test function which needs an argument of type "char *": void my_c_func(char * my_c_str) { printf(" my_c_str[%s]\n", my_c_str); } // This is a program which tests the conversion from "QString" to "char *": int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // Case 1: ASCII characters // ======================== QString qString1 = "French"; qDebug().nospace().noquote() << "qString1[" << qString1 << "]"; // qString1[French] // Solution 1.1: to Latin1 QByteArray, followed by data() in 2 steps: QByteArray latin1BAString1 = qString1.toLatin1(); char * latin1_c_str1 = latin1BAString1.data(); qDebug().nospace().noquote() << "latin1_c_str1[" << latin1_c_str1 << "]"; // latin1_c_str1[French] my_c_func(latin1_c_str1); // Solution 1.2: to local 8-bit QByteArray, followed by data() in 2 steps: QByteArray local8bitBAString1 = qString1.toLocal8Bit(); char * local8bit_c_str1 = local8bitBAString1.data(); qDebug().nospace().noquote() << "local8bit_c_str1[" << local8bit_c_str1 << "]"; // local8bit_c_str1[French] my_c_func(local8bit_c_str1); // Solution 1.3: to UTF8 QByteArray, followed by data() in 2 steps: QByteArray utf8BAString1 = qString1.toUtf8(); char * utf8_c_str1 = utf8BAString1.data(); qDebug().nospace().noquote() << "utf8_c_str1[" << utf8_c_str1 << "]"; // utf8_c_str1[French] my_c_func(utf8_c_str1); // !!! Try: Solution 1.4: to std::string , followed by c_str() in 2 steps: std::string stdString1 = qString1.toStdString(); const char * stdstring_c_str1 = stdString1.c_str(); // "const" must be used ! qDebug().nospace().noquote() << "stdstring_c_str1[" << stdstring_c_str1 << "]"; // stdstring_c_str1[French] // invalid conversion from 'const char*' to 'char*': ---> NOT GOOD for use by a C-style function !!! // my_c_func(stdstring_c_str1); qDebug() << ""; // Case 2: Non-ASCII characters // ============================ QString qString2 = "français"; qDebug().nospace().noquote() << "qString2[" << qString2 << "]"; // qString2[français] // !!! Try: Solution 2.1: to Latin1 QByteArray, followed by data() in 2 steps: QByteArray latin1BAString2 = qString2.toLatin1(); char * latin1_c_str2 = latin1BAString2.data(); qDebug().nospace().noquote() << "latin1_c_str2[" << latin1_c_str2 << "]"; // latin1_c_str2[fran?ais] ---> NOT GOOD for non-ASCII characters !!! my_c_func(latin1_c_str2); // Solution 2.2: to Local 8-bit QByteArray, followed by data() in 2 steps: QByteArray local8bitBAString2 = qString2.toLocal8Bit(); char * local8bit_c_str2 = local8bitBAString2.data(); qDebug().nospace().noquote() << "local8bit_c_str2[" << local8bit_c_str2 << "]"; // local8bit_c_str2[français] my_c_func(local8bit_c_str2); // Solution 2.3: to UTF8 QByteArray, followed by data() in 2 steps: QByteArray utf8BAString2 = qString2.toUtf8(); char * utf8_c_str2 = utf8BAString2.data(); qDebug().nospace().noquote() << "utf8_c_str2[" << utf8_c_str2 << "]"; // utf8_c_str2[français] my_c_func(utf8_c_str2); // !!! Try: Solution 2.4: to std::string, followed by c_str() in 2 steps: std::string stdString2 = qString2.toStdString(); const char * stdstring_c_str2 = stdString2.c_str(); // "const" must be used ! qDebug().nospace().noquote() << "stdstring_c_str2[" << stdstring_c_str2 << "]"; // stdstring_c_str2[français] // invalid conversion from 'const char*' to 'char*': ---> NOT GOOD for use by a C-style function !!! // my_c_func(stdstring_c_str2); return a.exec(); } 

The above code has been tested using Qt 5.4 for Linux.

The second question involved in this question is whether we can combine functions during this two-step conversion process:

<myQString>.to<AnotherClass>().<getCPointer>(); // OK or not?

I think it depends on "AnotherClass" and on the type of characters that need to be converted. Based on some documentation on QString, QByteArray and std :: string, it seems safe to write:

<myQString>.toStdString().c_str(); // OK.

<myQString>.toUtf8().data(); // Should be OK as QString is Unicode string.

But the following lines should be avoided:

<myQString>.toLocal8Bit().data(); // May crash if the converted QByteArray object is undefined !

<myQString>.toLatin1().data(); // May crash if the converted QByteArray object is undefined !

+1
source share

QString :: toLatin1 (). data () gives you const char * because it gives you its internal buffer. The reason it is connected is because you should not change it.

So, if you want to change it, you need to copy this data to another buffer ... for example, the one you just allocated using new ().

0
source share
 std::vector<char> result; result.reserve( qstr.length()+1 ); // +1 might not be needed, not sure how QString counts result.insert( result.end(), qstr.begin(), qstr.end() ); char* ptr = result.data(); // while retval exists, retval.data() is a char* pointing to a buffer 
0
source share

QByteArray contains a non-envelope version of data() . See: http://qt-project.org/doc/qt-5.0/qtcore/qbytearray.html#data

0
source share

I use this in my code all the time

 char * toCharP(QString in) { QByteArray a; a.append(in); return a.data(); } 
0
source share

Sometimes there is simply no way to keep the code in top beauty. Deal with it. You can wrap it in a small helper function by taking a QString in a parameter and returning char * if you really want to.

-one
source share

All Articles