Перетворення QString в char *


94

Я намагався перетворити QString на тип char * наступними методами, але, схоже, вони не працюють.

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

Чи можете ви розробити можливий недолік цього методу або запропонувати альтернативний метод?


Ваш приклад для мене чудово працює, де проблема?
Vesturs

3
Вибачте за мою англійську, але чому неправильно застосовувати такий підхід? QString s("some"); printf(reinterpret_cast<char *>(s.data()));
bartolo-otrit

Відповіді:


114

Ну, Qt FAQ говорить:

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

Тож, можливо, у вас інші проблеми. Як саме це не працює?


11
const char*і char*не є однотипними.
Гонки легкості на орбіті

3
@LightnessRacesinOrbit: писати на вміст QString, не знаючи цього, - це жахлива ідея, отже, звичайно, const char*це те, що дійсно можна отримати. Користувач може вільно копіювати дані до записуваного буфера.
Елі Бендерський,

1
Я цілком згоден. Однак питання, яке задавали char*, ні char const*, і ваша відповідь просто ігнорує цей факт без згадки.
Гонки легкості на орбіті

4
@LightnessRacesinOrbit: іноді найкраща відповідь - це не задавати питання. Іншими словами, вказати на те, що це не правильна річ. Цю відповідь прийняв плакат із запитаннями, тому, я гадаю, він досяг своєї мети
Елі Бендерський

2
здається, що FAQ було оновлено для використання toLocal8Bit()?
Ларрі

52

Може бути

my_qstring.toStdString().c_str();

або безпечніше, як зазначає Федеріко:

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

Це далеко не оптимально, але зробить свою роботу.


3
Це зіпсує символи Unicode. Юнікод-дружнє рішення: stackoverflow.com/a/4644922/238387
jlstrecker

21
Цей метод дуже небезпечний, і його не слід використовувати: toStdString()поверніть новий std::stringоб’єкт, після чого const char *отримаєте вказівник на внутрішні дані . Однак об'єкт рядка негайно знищується після цього оператора, тому вказівник результату, ймовірно, не має дійсної адреси, якщо ви використовуєте його в наступному операторі.
RicoRico

@RicoRico Не toStdString()небезпечний метод ; це використання сирих покажчиків. Або, більш конкретно, використання необроблених покажчиків від об’єктів, сфери застосування яких недостатньо зрозумілі.
нотлеш

Зокрема, тимчасові програми C ++ зазвичай живуть до кінця оператора, який їх створює. Отже, перша форма у відповіді - це нормально, якщо вона використовується в рядку у виклику функції (припускаючи, що функція не зберігає покажчик для подальшого використання), але це не нормально, якщо вона призначена змінній.
plugwash

46

Найпростіший спосіб перетворити QString на char * - це qPrintable (const QString & str) , який є макросом, що розширюється до str.toLocal8Bit().constData().


Чому це не більш популярна відповідь? Я щойно дізнався про це випадково, коли тикався навколо джерела Qt, і це саме те, що вони роблять.
Флулій

6
@Phlucious, тому що: 1) qPrintableповертає const char*не char*, str.toLocal8Bit().data()повертає char*. 2) Вказівник на const char*стає недійсним, як тільки ви натискаєте крапку з комою в операторі, де qPrintableбуло використано. Тому const char* c_ptr = s.toLocal8Bit().constData();не має сенсу.
WindyFields

1
@Phlucious спасибі, що ти рятувальник життя :) ці всі найкращі відповіді помилкові, Питання про char та вони повертають const char *
user889030

Чи qPrintableгарантовано вихід закінчується нулем?
Джованні Черретані

@WindyFields - Як застережено в qPrintable()описі: "Вказівник на символ буде недійсним після оператора, в якому використовується qPrintable ()."
Джеремі

6

Відповідь Девіда чудово працює, якщо ви використовуєте її лише для виведення у файл або для відображення на екрані, але якщо функція або бібліотека вимагає символу * для синтаксичного аналізу, тоді цей метод працює найкраще:

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

ВИДАЛЕНО

цей спосіб також працює

QString str ("Something");

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

Це схоже на інше перетворення ( std::stringQString), а не на те, про що просять.
Тобі Спейт,

3

Ваш рядок може містити символи не латиниці1, що веде до невизначених даних. Це залежить від того, що ви маєте на увазі під словами "це, здається, не працює".


2

правильне рішення було б таким

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

Забудьте використовувати кастинг у стилі С.
kyb

2

Якщо ваш рядок містить символи, що не є ASCII - краще зробити це таким чином: s.toUtf8().data()(або s->toUtf8().data())


0

Це життєздатний спосіб використовувати std :: vector як проміжний контейнер:

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

0

Qt забезпечує найпростіший API

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

Якщо ви хочете використовувати неконстантний вказівник даних

str.toLocal8Bit().data() or str.toUtf8().data()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.