Konversi QString ke char *

99

Saya mencoba mengonversi QString ke tipe char * dengan metode berikut, tetapi tampaknya tidak berhasil.

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

Dapatkah Anda menjelaskan kekurangan yang mungkin terjadi dengan metode ini, atau memberikan metode alternatif?

mawia
sumber
Teladan Anda bekerja dengan baik untuk saya, di mana masalahnya?
Viesturs
3
Maaf untuk bahasa Inggris saya tetapi mengapa tidak benar menggunakan pendekatan seperti itu? QString s("some"); printf(reinterpret_cast<char *>(s.data()));
bartolo-otrit

Jawaban:

118

Nah, FAQ Qt mengatakan:

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

Jadi mungkin Anda mengalami masalah lain. Bagaimana tepatnya ini tidak berhasil?

Eli Bendersky
sumber
11
const char*dan char*bukan tipe yang sama.
Balapan Ringan di Orbit
3
@LightnessRacesinOrbit: menulis ke konten QString tanpa sepengetahuannya adalah ide yang mengerikan, tentu saja const char*itulah yang benar-benar dapat diperoleh. Pengguna bebas menyalin data ke buffer yang dapat ditulis.
Eli Bendersky
1
Saya sangat setuju. Namun, pertanyaan yang diajukan tentang char*, bukan char const*, dan jawaban Anda mengabaikan fakta itu tanpa menyebutkan.
Balapan Ringan di Orbit
4
@LightnessRacesinOrbit: terkadang jawaban terbaik adalah dengan membuka pertanyaan. Dengan kata lain, untuk menunjukkan bahwa itu tidak menanyakan hal yang benar. Jawaban ini diterima oleh poster pertanyaan, jadi saya kira itu mencapai targetnya
Eli Bendersky
2
sepertinya FAQ telah diperbarui untuk digunakan toLocal8Bit()?
Larry
53

Mungkin

my_qstring.toStdString().c_str();

atau lebih aman, seperti yang ditunjukkan Federico:

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

Ini jauh dari optimal, tetapi akan berhasil.

davidnr
sumber
3
Ini akan mengacaukan karakter Unicode. Solusi ramah Unicode: stackoverflow.com/a/4644922/238387
jlstrecker
21
Metode ini sangat berbahaya dan tidak boleh digunakan: toStdString()kembalikan std::stringobjek baru dan kemudian penunjuk ke data internal const char *diperoleh. Namun, objek string segera dimusnahkan setelah pernyataan ini, jadi penunjuk hasil mungkin tidak memiliki alamat yang valid jika Anda menggunakannya dalam pernyataan berikutnya.
RicoRico
@RicoRico Bukan metode toStdString()yang berbahaya; itu penggunaan petunjuk mentah. Atau, lebih khusus lagi, penggunaan pointer mentah dari objek yang cakupannya tidak dipahami dengan baik.
notlesh
Khususnya sementara C ++ biasanya hidup sampai akhir pernyataan yang membuatnya. Jadi bentuk pertama dalam jawabannya tidak apa-apa jika digunakan secara in-line dalam pemanggilan fungsi (dengan asumsi fungsi tidak menyimpan penunjuk untuk penggunaan di masa mendatang) tetapi tidak baik jika ditempatkan ke variabel.
plugwash
46

Cara termudah untuk mengonversi QString ke char * adalah qPrintable (const QString & str) , yang merupakan perluasan makro str.toLocal8Bit().constData().

Robert
sumber
Mengapa ini bukan jawaban yang lebih populer? Saya baru saja mengetahui hal ini secara tidak sengaja saat melihat-lihat sumber Qt, dan itulah yang mereka lakukan.
Phlucious
6
@Phlucious, karena: 1) qPrintablekembali const char*tidak char*, str.toLocal8Bit().data()kembali char*. 2) Penunjuk const char*menjadi tidak valid segera setelah Anda menekan titik koma dalam pernyataan tempat qPrintabledigunakan. Jadi const char* c_ptr = s.toLocal8Bit().constData();tidak masuk akal.
WindyFields
1
@Phlucious thanks you are life saver :) ini semua jawaban pilihan teratas salah, Pertanyaan tentang char dan mereka kembali const char *
user889030
Apakah qPrintableoutput dijamin nol dihentikan?
Giovanni Cerretani
@WindyFields - Seperti yang diperingatkan dalam qPrintable()deskripsi: "Pointer char tidak akan valid setelah pernyataan di mana qPrintable () digunakan."
Jeremy
6

Jawaban David berfungsi dengan baik jika Anda hanya menggunakannya untuk keluaran ke file atau ditampilkan di layar, tetapi jika fungsi atau pustaka memerlukan karakter * untuk parsing, maka metode ini berfungsi paling baik:

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

DIEDIT

cara ini juga berhasil

QString str ("Something");

char* ch = str.toStdString().C_str();
Shanks
sumber
Itu terlihat seperti konversi yang berbeda ( std::stringQString), bukan apa yang diminta.
Toby Speight
3

String Anda mungkin berisi karakter non Latin1, yang mengarah ke data yang tidak ditentukan. Itu tergantung dari apa yang Anda maksud dengan "sepertinya tidak berhasil".

gregseth
sumber
2

Solusi yang Benar Akan seperti ini

   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
sumber
Lupakan menggunakan casting gaya C.
kyb
2

Jika string Anda berisi karakter non-ASCII - lebih baik melakukannya dengan cara ini: s.toUtf8().data()(atau s->toUtf8().data())

AlexDarkVoid
sumber
0

Ini adalah cara yang layak untuk menggunakan std :: vector sebagai penampung perantara:

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

Qt menyediakan API paling sederhana

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

Jika Anda ingin menggunakan penunjuk data non-const

str.toLocal8Bit().data()
str.toUtf8().data()
pengguna2042397
sumber