Преобразование QString в char *

99

Я пытался преобразовать 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());

Можете ли вы уточнить возможные недостатки этого метода или предложить альтернативный метод?

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

Ответы:

118

Что ж, 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()?
Ларри
53

Может быть

my_qstring.toStdString().c_str();

или безопаснее, как отмечает Федерико:

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

Это далеко не оптимально, но сработает.

Дэвиднр
источник
3
Это испортит символы Unicode. Решение для Unicode: stackoverflow.com/a/4644922/238387
jlstrecker
21
Этот метод очень опасен, и его не следует использовать: toStdString()вернуть новый std::stringобъект, и тогда const char *будет получен указатель на внутренние данные . Однако строковый объект сразу же уничтожается после этого оператора, поэтому указатель результата, вероятно, не имеет действительного адреса, если вы используете его в следующем операторе.
RicoRico
@RicoRico Это не метод, toStdString()который опасен; это использование необработанных указателей. Или, более конкретно, использование необработанных указателей от объектов, область действия которых не совсем понятна.
notlesh
В частности, временные библиотеки C ++ обычно живут до конца оператора, который их создает. Итак, первая форма в ответе допустима, если она используется в вызове функции (при условии, что функция не хранит указатель для будущего использования), но это не нормально, если она назначена переменной.
plugwash
46

Самый простой способ преобразовать QString в char * - это qPrintable (const QString & str) , который является макросом, расширяющимся до str.toLocal8Bit().constData().

Роберт
источник
Почему это не более популярный ответ? Я узнал об этом случайно, когда копался в исходниках Qt, и именно это они и делают.
Phlucious
6
@Phlucious, потому что: 1) qPrintableвозвращает const char*не char*, str.toLocal8Bit().data()возвращается char*. 2) Указатель на const char*становится недействительным, как только вы ставите точку с запятой в операторе, где qPrintableбыл использован. Так const char* c_ptr = s.toLocal8Bit().constData();что смысла нет.
WindyFields
1
@ Доброе спасибо, что вы спасаете жизнь :) все эти самые популярные ответы неверны. Вопрос о char, и они возвращают const char *
user889030
qPrintableГарантируется ли вывод, что нулевое завершение?
Джованни Черретани,
@WindyFields - Как указано в qPrintable()описании: «Указатель char будет недействительным после оператора, в котором используется qPrintable ()».
Джереми
6

Ответ Дэвида работает нормально, если вы используете его только для вывода в файл или отображения на экране, но если функция или библиотека требует char * для синтаксического анализа, то этот метод работает лучше всего:

// 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
источник
4

ИЗМЕНЕНО

этот способ тоже работает

QString str ("Something");

char* ch = str.toStdString().C_str();
Шэнкс
источник
Это похоже на другое преобразование ( std::stringQString), а не на то, о чем просили.
Тоби Спейт
3

Ваша строка может содержать символы, отличные от Latin1, что приводит к неопределенным данным. Это зависит от того, что вы подразумеваете под «похоже, это не работает».

Грегсет
источник
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<<"<---";
Сэм
источник
Забудьте использовать кастинг в стиле C.
kyb
2

Если ваша строка содержит символы, отличные от ASCII - лучше сделать это так: s.toUtf8().data()(или s->toUtf8().data())

AlexDarkПустота
источник
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)
const char *qUtf8Printable(const QString &str)

Если вы хотите использовать неконстантный указатель данных

str.toLocal8Bit().data()
str.toUtf8().data()
user2042397
источник