J'ai un code moche pour ce genre de choses (créer un pointeur de char c et y copier la chaîne QString), mais peut-être ... existe-t-il dans QT de manière élégante ...
code actuel:
QString maquina is a method parameter.
char *c_maquina = new char[maquina.length() + 1];
strcpy(c_maquina, maquina.toStdString().c_str());
juste pour information, j'ai besoin d'un vrai caractère * et non d'un simple caractère constant *, donc ce code ne fonctionne pas:
idMaquina.toLatin1().data();
Je ne peux pas utiliser http://developer.qt.nokia.com/faq/answer/how_can_i_convert_a_qstring_to_char_and_vice_versa
C'est simple:
QByteArray array = string.toLocal8Bit();
char* buffer = array.data();
Vous pouvez également utiliser toLatin1
ou toUtf8
au lieu de toLocal8Bit
. Notez qu'aucun d'entre eux ne peut être mis en file d'attente avec l'appel data
. Et toStdString().c_str()
est également invalide. En effet, toute QByteArray
ou std::string
produite de cette manière est temporaire et sera détruite immédiatement en détruisant le tampon de char avec ce dernier. Vous devez stocker QByteArray
dans une variable locale lorsque vous utilisez le tampon.
Notez également que Qt fournit la classe QByteArray
pour traiter les tableaux de caractères. En règle générale, il n'est pas nécessaire d'utiliser char*
, vous pouvez presque tout faire avec QByteArray
.
Je pense que la solution dépend du type de caractères à convertir et de la question de savoir si une fonction de style C avec des arguments de type "char *" doit être intégrée/appelée.
Si plusieurs solutions peuvent être utilisées pour votre cas spécifique, leur efficacité peut être légèrement différente, ce que je n’ai pas testé.
Le programme de test suivant montre comment utiliser ces 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();
}
Le code ci-dessus a été testé avec Qt 5.4 pour Linux.
Un deuxième sujet abordé dans cette question est de savoir si nous pouvons chaîner des fonctions ensemble au cours de ce processus de conversion en deux étapes:
<myQString>.to<AnotherClass>().<getCPointer>(); // OK or not?
Je pense que cela dépend de "AnotherClass" et du type de caractères à convertir. Basé sur de la documentation sur QString, QByteArray et std :: string, il apparaît qu’il est sécuritaire d’écrire:
<myQString>.toStdString().c_str(); // OK.
<myQString>.toUtf8().data(); // Should be OK as QString is Unicode string.
Mais les lignes suivantes doivent être évitées:
<myQString>.toLocal8Bit().data(); // May crash if the converted QByteArray object is undefined !
<myQString>.toLatin1().data(); // May crash if the converted QByteArray object is undefined !
Je l'utilise tout le temps dans mon code
char * toCharP(QString in)
{
QByteArray a; a.append(in);
return a.data();
}
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
QString :: toLatin1 (). Data () vous donne un caractère constant * car il vous donne son tampon interne. C'est parce que vous n'êtes pas censé le modifier.
Donc, si vous voulez le modifier, vous devez copier ces données dans un autre tampon ... comme celui que vous venez d'allouer avec new ().
QByteArray contient une version non constante de data()
. Voir: http://qt-project.org/doc/qt-5.0/qtcore/qbytearray.html#data