QString'den char * 'a dönüştürme


99

Aşağıdaki yöntemlerle bir QString'i char * türüne dönüştürmeye çalışıyordum, ancak çalışmıyorlar.

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

Bu yöntemle olası kusuru detaylandırabilir misiniz veya alternatif bir yöntem verebilir misiniz?


Örneğiniz benim için iyi çalışıyor, sorun nerede?
Viesturs

3
İngilizcem için üzgünüm ama neden böyle bir yaklaşımı kullanmak doğru değil? QString s("some"); printf(reinterpret_cast<char *>(s.data()));
bartolo-otrit

Yanıtlar:


118

Eh, Qt SSS diyor:

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

Yani belki başka problemleriniz var. Bu tam olarak nasıl çalışmıyor?


11
const char*ve char*aynı tip değil.
Orbit'te Hafiflik Yarışları

4
@LightnessRacesinOrbit: QString'in içeriğine bilmeden yazmak korkunç bir fikir, dolayısıyla const char*gerçekten elde edilebilecek şey bu. Kullanıcı, verileri yazılabilir bir arabelleğe kopyalamakta serbesttir.
Eli Bendersky

1
Tamamen katılıyorum. Bununla birlikte, sorulan soru char*değil char const*ve cevabınız bu gerçeği bahsetmeden görmezden geliyor.
Orbit'te Hafiflik Yarışları

5
@LightnessRacesinOrbit: Bazen en iyi cevap soruyu sormamaktır. Başka bir deyişle, doğru şeyi sormadığını belirtmek için. Bu cevap soru posteri tarafından kabul edildi, bu yüzden sanırım hedefine ulaştı
Eli Bendersky

2
SSS kullanım için güncellenmiş gibi görünüyor toLocal8Bit()?
Larry

55

Olabilir

my_qstring.toStdString().c_str();

veya Federico'nun işaret ettiği gibi daha güvenli:

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

Optimal olmaktan uzak, ama işi yapacak.


3
Bu, Unicode karakterlerini bozacaktır. Unicode dostu bir çözüm: stackoverflow.com/a/4644922/238387
jlstrecker

21
Bu yöntem çok tehlikelidir ve kullanılmamalıdır: toStdString()yeni bir std::stringnesne döndürür ve ardından dahili verilere işaretçi const char *elde edilir. Bununla birlikte, dize nesnesi bu ifadeden hemen sonra yok edilir, bu nedenle, sonraki bir ifadede kullanırsanız, sonuç göstericisinin muhtemelen geçerli bir adresi yoktur.
RicoRico

@RicoRico toStdString()Tehlikeli olan yöntem değil ; ham işaretçilerin kullanılmasıdır. Ya da daha spesifik olarak, kapsamları iyi anlaşılmayan nesnelerden ham işaretçilerin kullanılması.
notlesh

Spesifik olarak C ++ geçicileri normalde onları oluşturan ifadenin sonuna kadar yaşarlar. Yani cevaptaki ilk form, bir fonksiyon çağrısında satır içi kullanılıyorsa uygundur (fonksiyonun ileride kullanılmak üzere göstericiyi saklamadığı varsayılarak), ancak bir değişkene atanmışsa uygun değildir.
1919

50

Bir dönüştürmek için en kolay yolu QString için Char * olan (QString & str const) qPrintable için genişleyen bir makro olduğunu str.toLocal8Bit().constData().


Bu neden daha popüler bir cevap değil? Bunu Qt kaynağına bakarken kazara öğrendim ve yaptıkları da tam olarak bu.
Phlucious

6
@Phlucious, çünkü: 1) qPrintabledöndürür const char*değil char*, str.toLocal8Bit().data()döner char*. 2) Kullanıldığı const char*ifadede bir noktalı virgülle vurduğunuz anda işaretçi geçersiz hale gelir qPrintable. Yani const char* c_ptr = s.toLocal8Bit().constData();hiç mantıklı değil.
WindyFields

1
@Phlucious teşekkürler, hayat kurtarıcısınız :) bu en çok oylanan cevapların hepsi yanlış, Soru char hakkında ve geri dönüyorlar const char *
user889030

Mi qPrintableçıkış sıfır sona garanti?
Giovanni Cerretani

@WindyFields - qPrintable()Açıklamada uyarıldığı gibi : "qPrintable () kullanıldığı ifadeden sonra karakter işaretçisi geçersiz olacaktır."
Jeremy

6

David'in cevabı, onu yalnızca bir dosyaya çıktı almak veya ekranda görüntülemek için kullanıyorsanız iyi çalışıyor, ancak bir işlev veya kitaplık ayrıştırma için bir char * gerektiriyorsa, bu yöntem en iyi sonucu verir:

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

DÜZENLENDİ

bu şekilde de çalışır

QString str ("Something");

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

Bu , istenen şey değil, farklı bir dönüşüme ( std::stringQString) benziyor .
Toby Speight

3

Diziniz Latin1 olmayan karakterler içerebilir ve bu da tanımlanmamış verilere yol açar. "İşe yaramıyor" derken ne demek istediğine bağlı.


2

Doğru Çözüm böyle olurdu

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

C tarzı dökümü kullanmayı unutun.
kyb

2

Dizeniz ASCII olmayan karakterler içeriyorsa - bunu şu şekilde yapmak daha iyidir: s.toUtf8().data()(veya s->toUtf8().data())


0

Std :: vector'u bir ara kap olarak kullanmanın uygun bir yoludur:

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

0

Qt, en basit API'yi sağlar

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

Sabit olmayan veri işaretçisi istiyorsanız şunu kullanın:

str.toLocal8Bit().data()
str.toUtf8().data()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.