Conversion de QString en char *

94

J'essayais de convertir un QString en type char * par les méthodes suivantes, mais elles ne semblent pas fonctionner.

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

Pouvez-vous expliquer le défaut possible avec cette méthode, ou donner une méthode alternative?

mawia
la source
Votre exemple fonctionne bien pour moi, où est le problème?
Viesturs
3
Désolé pour mon anglais mais pourquoi il n'est pas juste d'utiliser une telle approche? QString s("some"); printf(reinterpret_cast<char *>(s.data()));
bartolo-otrit

Réponses:

114

Eh bien, la FAQ Qt dit:

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

Alors peut-être que vous rencontrez d'autres problèmes. Comment cela ne fonctionne-t-il pas exactement?

Eli Bendersky
la source
11
const char*et char*ne sont pas du même type.
Courses de légèreté en orbite
3
@LightnessRacesinOrbit: écrire sur le contenu de QString sans qu'il le sache est une idée horrible, donc bien sûr, const char*c'est ce qui peut vraiment être obtenu. L'utilisateur est libre de copier les données dans un tampon inscriptible.
Eli Bendersky
1
Je suis complètement d'accord. Cependant, la question posée sur char*, non char const*, et votre réponse ignore tout simplement ce fait sans le mentionner.
Courses de légèreté en orbite
4
@LightnessRacesinOrbit: parfois la meilleure réponse est de démasquer la question. En d'autres termes, souligner qu'il ne s'agit pas de demander la bonne chose. Cette réponse a été acceptée par l'affiche de la question, donc je suppose qu'elle a atteint son objectif
Eli Bendersky
2
semble que la FAQ a été mise à jour pour être utilisée toLocal8Bit()?
Larry
52

Peut être

my_qstring.toStdString().c_str();

ou plus sûr, comme le souligne Federico:

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

C'est loin d'être optimal, mais fera le travail.

Davidnr
la source
3
Cela gâchera les caractères Unicode. Une solution compatible Unicode: stackoverflow.com/a/4644922/238387
jlstrecker
21
Cette méthode est très dangereuse et ne doit pas être utilisée: toStdString()retournez un nouvel std::stringobjet puis le pointeur vers les données internes const char *est obtenu. Toutefois, l'objet chaîne est immédiatement détruit après cette instruction, de sorte que le pointeur de résultat n'a probablement pas d'adresse valide si vous l'utilisez dans une instruction ultérieure.
RicoRico
@RicoRico Ce n'est pas la méthode toStdString()qui est dangereuse; c'est l'utilisation de pointeurs bruts. Ou, plus précisément, l'utilisation de pointeurs bruts à partir d'objets dont les portées ne sont pas bien comprises.
notlesh
Plus précisément, les temporaires C ++ vivent normalement jusqu'à la fin de l'instruction qui les crée. Donc, le premier formulaire de la réponse est correct s'il est utilisé en ligne dans un appel de fonction (en supposant que la fonction ne stocke pas le pointeur pour une utilisation future) mais ce n'est pas correct s'il est affecté à une variable.
plugwash
46

Le moyen le plus simple de convertir une QString en char * est qPrintable (const QString & str) , qui est une macro se développant en str.toLocal8Bit().constData().

Robert
la source
Pourquoi n'est-ce pas une réponse plus populaire? Je viens d'apprendre cela par accident en fouettant dans la source Qt, et c'est exactement ce qu'ils font.
Phlucious
6
@Phlucious, car: 1) qPrintablerenvoie const char*non char*, str.toLocal8Bit().data()retourne char*. 2) Le pointeur vers const char*devient invalide dès que vous appuyez sur un point-virgule dans l'instruction où a qPrintableété utilisé. Cela const char* c_ptr = s.toLocal8Bit().constData();n'a donc aucun sens.
WindyFields
1
@Phlucious merci, vous êtes sauveur de vie :) ces toutes les réponses les plus votées sont fausses, la question concerne char et ils retournent const char *
user889030
La qPrintablesortie est-elle garantie à zéro?
Giovanni Cerretani
@WindyFields - Comme averti dans la qPrintable()description: "Le pointeur char sera invalide après l'instruction dans laquelle qPrintable () est utilisé."
Jeremy
6

La réponse de David fonctionne bien si vous ne l'utilisez que pour la sortie dans un fichier ou l'affichage à l'écran, mais si une fonction ou une bibliothèque nécessite un char * pour l'analyse, alors cette méthode fonctionne mieux:

// 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);
Alex
la source
4

ÉDITÉ

cette façon fonctionne aussi

QString str ("Something");

char* ch = str.toStdString().C_str();
Shanks
la source
Cela ressemble à une conversion différente ( std::stringQString), pas à ce qui est demandé.
Toby Speight
3

Votre chaîne peut contenir des caractères non Latin1, ce qui conduit à des données non définies. Cela dépend de ce que vous entendez par «ça ne semble pas fonctionner».

Gregseth
la source
2

la bonne solution serait comme ça

   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<<"<---";
sam
la source
Oubliez d'utiliser le casting de style C.
kyb
2

Si votre chaîne contient des caractères non ASCII, il est préférable de le faire de cette façon: s.toUtf8().data()(ou s->toUtf8().data())

AlexDarkVoid
la source
0

C'est un moyen viable d'utiliser std :: vector comme conteneur intermédiaire:

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

Qt fournit l'API la plus simple

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

Si vous souhaitez utiliser un pointeur de données non const

str.toLocal8Bit().data() or str.toUtf8().data()
user2042397
la source