Conversione da QString a char *


94

Stavo cercando di convertire un QString in char * type con i seguenti metodi, ma non sembrano funzionare.

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

Puoi elaborare il possibile difetto con questo metodo o fornire un metodo alternativo?


Il tuo esempio funziona bene per me, dov'è il problema?
Viesturs

3
Scusa per il mio inglese, ma perché non è giusto usare questo approccio? QString s("some"); printf(reinterpret_cast<char *>(s.data()));
bartolo-otrit

Risposte:


114

Bene, la FAQ Qt dice:

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

Quindi forse hai altri problemi. Come non funziona esattamente?


11
const char*e char*non sono dello stesso tipo.
Gare di leggerezza in orbita

3
@LightnessRacesinOrbit: scrivere sul contenuto di QString senza che lo sappia è un'idea orribile, quindi ovviamente const char*è ciò che si può davvero ottenere. L'utente è libero di copiare i dati in un buffer scrivibile.
Eli Bendersky

1
Sono completamente d'accordo. Tuttavia, la domanda posta in merito char*, no char const*, e la tua risposta ignora semplicemente questo fatto senza menzionarlo.
Gare di leggerezza in orbita

4
@LightnessRacesinOrbit: a volte la risposta migliore è rimuovere la domanda. In altre parole, per sottolineare che non è chiedere la cosa giusta. Questa risposta è stata accettata dal poster della domanda, quindi suppongo che abbia raggiunto il suo obiettivo
Eli Bendersky

2
sembra che le FAQ siano state aggiornate per l'uso toLocal8Bit()?
Larry

52

Può essere

my_qstring.toStdString().c_str();

o più sicuro, come sottolinea Federico:

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

È tutt'altro che ottimale, ma farà il lavoro.


3
Questo rovinerà i caratteri Unicode. Un Unicode-friendly soluzione: stackoverflow.com/a/4644922/238387
jlstrecker

21
Questo metodo è molto pericoloso e non dovrebbe essere utilizzato: toStdString()restituisce un nuovo std::stringoggetto e quindi const char *si ottiene il puntatore ai dati interni . Tuttavia, l'oggetto stringa viene immediatamente distrutto dopo questa istruzione, quindi il puntatore del risultato probabilmente non ha un indirizzo valido se lo si utilizza in un'istruzione successiva.
RicoRico

@RicoRico Non è il metodo toStdString()che è pericoloso; è l'uso di puntatori grezzi. O, più specificamente, l'uso di puntatori non elaborati da oggetti i cui ambiti non sono ben compresi.
notlesh

In particolare, i provvisori C ++ normalmente vivono fino alla fine dell'istruzione che li crea. Quindi la prima forma nella risposta è ok se è usata in linea in una chiamata di funzione (supponendo che la funzione non memorizzi il puntatore per un uso futuro) ma non va bene se è assegnata a una variabile.
plugwash

46

Il modo più semplice per convertire una QString in char * è qPrintable (const QString & str) , che è una macro che si espande in str.toLocal8Bit().constData().


Perché questa non è una risposta più popolare? L'ho saputo per caso mentre frugavo nella fonte Qt, ed è esattamente quello che fanno.
Phlucious

6
@Phlucious, perché: 1) qPrintableritorna const char*non char*, str.toLocal8Bit().data()i rendimenti char*. 2) Il puntatore a const char*diventa non valido non appena si preme un punto e virgola nell'istruzione in cui è qPrintablestato utilizzato. Quindi const char* c_ptr = s.toLocal8Bit().constData();non ha alcun senso.
WindyFields

1
@Phlucious grazie sei salvavita :) queste tutte le risposte più votate sono sbagliate, la domanda riguarda char e stanno restituendo const char *
user889030

È qPrintablegarantito che l'uscita sia terminata con zero?
Giovanni Cerretani

@WindyFields - Come avvertito nella qPrintable()descrizione: "Il puntatore char non sarà valido dopo l'istruzione in cui viene utilizzato qPrintable ()."
Jeremy

6

La risposta di David funziona bene se la stai usando solo per l'output in un file o la visualizzazione sullo schermo, ma se una funzione o una libreria richiede un carattere * per l'analisi, questo metodo funziona meglio:

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

MODIFICATO

funziona anche in questo modo

QString str ("Something");

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

Sembra una conversione diversa ( std::stringQString), non quella richiesta.
Toby Speight

3

La tua stringa può contenere caratteri non Latin1, il che porta a dati non definiti. Dipende da cosa intendi per "non sembra funzionare".


2

la soluzione corretta sarebbe così

   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<<"<---";

Dimentica di usare il casting in stile C.
kyb

2

Se la tua stringa contiene caratteri non ASCII, è meglio farlo in questo modo: s.toUtf8().data()(o s->toUtf8().data())


0

È un modo praticabile per usare std :: vector come contenitore intermedio:

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

0

Qt fornisce l'API più semplice

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

Se si desidera utilizzare un puntatore ai dati non const

str.toLocal8Bit().data() or str.toUtf8().data()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.