QString zu char * Konvertierung

92

Ich habe versucht, einen QString mit den folgenden Methoden in den Typ char * zu konvertieren, aber sie scheinen nicht zu funktionieren.

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

Können Sie den möglichen Fehler mit dieser Methode erläutern oder eine alternative Methode angeben?

Mawia
quelle
Ihr Beispiel funktioniert gut für mich, wo liegt das Problem?
Viesturs
3
Entschuldigung für mein Englisch, aber warum ist es nicht richtig, einen solchen Ansatz zu verwenden? QString s("some"); printf(reinterpret_cast<char *>(s.data()));
Bartolo-Otrit

Antworten:

114

Nun, die Qt FAQ sagt:

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

Vielleicht haben Sie andere Probleme. Wie genau funktioniert das nicht?

Eli Bendersky
quelle
11
const char*und char*sind nicht der gleiche Typ.
Leichtigkeitsrennen im Orbit
3
@LightnessRacesinOrbit: Das Schreiben in den Inhalt von QString ohne dessen Wissen ist eine schreckliche Idee, daher const char*kann man natürlich wirklich etwas erreichen. Dem Benutzer steht es frei, die Daten in einen beschreibbaren Puffer zu kopieren.
Eli Bendersky
1
Ich stimme vollkommen zu. Die gestellte Frage lautet jedoch char*nicht char const*, und Ihre Antwort ignoriert diese Tatsache einfach ohne Erwähnung.
Leichtigkeitsrennen im Orbit
4
@LightnessRacesinOrbit: Manchmal ist es die beste Antwort, die Frage zu entlarven. Mit anderen Worten, um darauf hinzuweisen, dass es nicht das Richtige ist. Diese Antwort wurde vom Fragenplakat akzeptiert, also hat es wohl sein Ziel erreicht
Eli Bendersky
2
scheint, dass die FAQ aktualisiert wurde, um zu verwenden toLocal8Bit()?
Larry
49

Vielleicht

my_qstring.toStdString().c_str();

oder sicherer, wie Federico betont:

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

Es ist alles andere als optimal, wird aber die Arbeit erledigen.

davidnr
quelle
3
Dies wird Unicode-Zeichen durcheinander bringen. Eine Unicode-freundliche Lösung: stackoverflow.com/a/4644922/238387
jlstrecker
21
Diese Methode ist sehr gefährlich und sollte nicht verwendet werden: toStdString()Geben Sie ein neues std::stringObjekt zurück und der Zeiger auf interne Daten const char *wird abgerufen. Das Zeichenfolgenobjekt wird jedoch sofort nach dieser Anweisung zerstört, sodass der Ergebniszeiger wahrscheinlich keine gültige Adresse hat, wenn Sie ihn in einer nachfolgenden Anweisung verwenden.
RicoRico
@RicoRico Es ist nicht die Methode toStdString(), die gefährlich ist; Es ist die Verwendung von rohen Zeigern. Oder genauer gesagt, die Verwendung von Rohzeigern von Objekten, deren Bereiche nicht gut verstanden werden.
Notlesh
Insbesondere C ++ - Temporaries leben normalerweise bis zum Ende der Anweisung, mit der sie erstellt werden. Das erste Formular in der Antwort ist also in Ordnung, wenn es in einem Funktionsaufruf inline verwendet wird (vorausgesetzt, die Funktion speichert den Zeiger nicht für die zukünftige Verwendung), aber es ist nicht in Ordnung, wenn es einer Variablen zugewiesen ist.
Plugwash
45

Der einfachste Weg, einen QString in char * zu konvertieren , ist qPrintable (const QString & str) , ein Makro, das auf erweitert wird str.toLocal8Bit().constData().

Robert
quelle
Warum ist dies keine populärere Antwort? Ich habe dies zufällig durch Stöbern in der Qt-Quelle erfahren, und genau das tun sie.
Phlucious
6
@Phlucious, weil: 1) qPrintablekehrt const char*nicht char*, str.toLocal8Bit().data()kehrt char*. 2) Der Zeiger auf const char*wird ungültig, sobald Sie ein Semikolon in der Anweisung drücken, in der er qPrintableverwendet wurde. Macht const char* c_ptr = s.toLocal8Bit().constData();also keinen Sinn.
WindyFields
1
@Phlucious danke, dass Sie Lebensretter sind :) diese alle am besten bewerteten Antworten sind falsch, Frage ist über char und sie geben const char zurück *
user889030
Ist die qPrintableAusgabe garantiert mit Null abgeschlossen?
Giovanni Cerretani
@WindyFields - Wie in der qPrintable()Beschreibung gewarnt : "Der Zeichenzeiger ist nach der Anweisung, in der qPrintable () verwendet wird, ungültig."
Jeremy
6

Davids Antwort funktioniert einwandfrei, wenn Sie sie nur zum Ausgeben in eine Datei oder zum Anzeigen auf dem Bildschirm verwenden. Wenn für eine Funktion oder Bibliothek jedoch ein Zeichen * zum Parsen erforderlich ist, funktioniert diese Methode am besten:

// 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
quelle
4

BEARBEITET

Dieser Weg funktioniert auch

QString str ("Something");

char* ch = str.toStdString().C_str();
Schenkel
quelle
Das sieht nach einer anderen Konvertierung aus ( std::stringQString), nicht nach dem, was verlangt wird.
Toby Speight
3

Ihre Zeichenfolge kann Nicht-Latin1-Zeichen enthalten, was zu undefinierten Daten führt. Es hängt davon ab, was Sie unter "es scheint nicht zu funktionieren" verstehen.

gregseth
quelle
2

Die richtige Lösung wäre so

   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
quelle
Vergessen Sie das Casting im C-Stil.
Kyb
2

Wenn Ihre Zeichenfolge Nicht-ASCII-Zeichen enthält, ist es besser, dies folgendermaßen zu tun: s.toUtf8().data()(oder s->toUtf8().data())

AlexDarkVoid
quelle
0

Es ist eine praktikable Möglichkeit, std :: vector als Zwischencontainer zu verwenden:

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

Qt bietet die einfachste API

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

Wenn Sie einen nicht konstanten Datenzeiger verwenden möchten

str.toLocal8Bit().data() or str.toUtf8().data()
user2042397
quelle