Conversión de QString a char *

94

Estaba intentando convertir un QString al tipo char * mediante los siguientes métodos, pero parece que no funcionan.

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

¿Puede explicar el posible defecto de este método o dar un método alternativo?

mawia
fuente
Tu ejemplo me funciona bien, ¿dónde está el problema?
Viesturs
3
Perdón por mi inglés, pero ¿por qué no es correcto utilizar ese enfoque? QString s("some"); printf(reinterpret_cast<char *>(s.data()));
bartolo-otrit

Respuestas:

114

Bueno, las preguntas frecuentes de Qt dicen:

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

Quizás tengas otros problemas. ¿Cómo no funciona esto exactamente?

Eli Bendersky
fuente
11
const char*y char*no son del mismo tipo.
Lightness Races in Orbit
3
@LightnessRacesinOrbit: escribir en el contenido de QString sin que él lo sepa es una idea horrible, por lo que, por supuesto, const char*es lo que realmente se puede obtener. El usuario es libre de copiar los datos a un búfer grabable.
Eli Bendersky
1
Estoy completamente de acuerdo. Sin embargo, la pregunta sobre char*, no char const*, y su respuesta simplemente ignora ese hecho sin mencionarlo.
Lightness Races in Orbit
4
@LightnessRacesinOrbit: a veces la mejor respuesta es no responder la pregunta. En otras palabras, señalar que no es pedir lo correcto. Esta respuesta fue aceptada por el cartel de la pregunta, así que supongo que dio en el blanco
Eli Bendersky
2
parece que las preguntas frecuentes se han actualizado para su uso toLocal8Bit()?
Larry
52

Tal vez

my_qstring.toStdString().c_str();

o más seguro, como señala Federico:

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

Está lejos de ser óptimo, pero hará el trabajo.

Davidnr
fuente
3
Esto estropeará los caracteres Unicode. Una solución compatible con Unicode: stackoverflow.com/a/4644922/238387
jlstrecker
21
Este método es muy peligroso y no debe usarse: toStdString()devuelve un nuevo std::stringobjeto y luego const char *se obtiene el puntero a los datos internos . Sin embargo, el objeto de cadena se destruye inmediatamente después de esta declaración, por lo que el puntero de resultado probablemente no tenga una dirección válida si lo usa en una declaración posterior.
RicoRico
@RicoRico No es el método lo toStdString()que es peligroso; es el uso de punteros sin procesar. O, más específicamente, el uso de punteros sin procesar de objetos cuyos alcances no se comprenden bien.
notlesh
Específicamente, los temporales de C ++ normalmente viven hasta el final de la declaración que los crea. Entonces, el primer formulario en la respuesta está bien si se usa en línea en una llamada de función (asumiendo que la función no almacena el puntero para uso futuro) pero no está bien si está asignado a una variable.
Plugwash
46

La forma más fácil de convertir un QString a char * es qPrintable (const QString & str) , que es una macro que se expande a str.toLocal8Bit().constData().

Robert
fuente
¿Por qué no es esta una respuesta más popular? Me enteré de esto por accidente mientras hurgaba en la fuente Qt, y eso es exactamente lo que hacen.
Phlucious
6
@Phlucious, debido a que: 1) qPrintablevuelve const char*no char*, str.toLocal8Bit().data()vuelve char*. 2) El puntero a se const char*vuelve inválido tan pronto como presione un punto y coma en la instrucción donde qPrintablese usó. Entonces const char* c_ptr = s.toLocal8Bit().constData();no tiene ningún sentido.
WindyFields
1
@Phlucious gracias, eres un salvavidas :) estas respuestas más votadas son incorrectas, la pregunta es sobre char y están devolviendo const char *
user889030
¿Se qPrintablegarantiza que la salida termina en cero?
Giovanni Cerretani
@WindyFields - Como se advierte en la qPrintable()descripción: "El puntero char no será válido después de la declaración en la que se usa qPrintable ()".
Jeremy
6

La respuesta de David funciona bien si solo la está usando para enviar a un archivo o mostrarla en la pantalla, pero si una función o biblioteca requiere un carácter * para analizar, este método funciona mejor:

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

EDITADO

de esta manera también funciona

QString str ("Something");

char* ch = str.toStdString().C_str();
Shanks
fuente
Eso parece una conversión diferente ( std::stringQString), no lo que se solicita.
Toby Speight
3

Su cadena puede contener caracteres que no sean Latin1, lo que conduce a datos indefinidos. Depende de lo que quieras decir con "no parece funcionar".

Gregseth
fuente
2

la solución correcta sería así

   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
fuente
Olvídese de usar la fundición estilo C.
kyb
2

Si su cadena contiene caracteres que no son ASCII, es mejor hacerlo de esta manera: s.toUtf8().data()(o s->toUtf8().data())

AlexDarkVoid
fuente
0

Es una forma viable de usar std :: vector como contenedor intermedio:

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

Qt proporciona la API más simple

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

Si desea utilizar un puntero de datos no constante

str.toLocal8Bit().data() or str.toUtf8().data()
usuario2042397
fuente