¿Cómo convertir QString a std :: string?


229

Estoy tratando de hacer algo como esto:

QString string;
// do things...
std::cout << string << std::endl;

pero el código no se compila. ¿Cómo enviar el contenido de qstring a la consola (por ejemplo, para propósitos de depuración u otras razones)? ¿Cómo convertir QStringa std::string?

Respuestas:


223

Una de las cosas que debe recordar al convertir QStringa std::stringes el hecho de que QStringes UTF-16 codificado, mientras que std::string... puede tener cualquier codificaciones.

Entonces lo mejor sería:

QString qs;

// Either this if you use UTF-8 anywhere
std::string utf8_text = qs.toUtf8().constData();

// or this if you're on Windows :-)
std::string current_locale_text = qs.toLocal8Bit().constData();

El método sugerido (aceptado) puede funcionar si especifica el códec.

Ver: http://doc.qt.io/qt-5/qstring.html#toLatin1


Esto no es seguro y es un poco más lento que la forma correcta. Está accediendo a los datos de un QByteArray creado en la pila. El destructor para QByteArray puede llamarse antes que el constructor de la cadena STL. La forma más segura de crear una función auxiliar. static inline std::string toUtf8(const QString& s) { QByteArray sUtf8 = s.toUtf8(); return std::string(sUtf8.constData(), sUtf8.size()); }
Vitali

17
@Vitali no es correcto. "El destructor para QByteArray puede ser llamado antes que el constructor de la cadena STL" no es una declaración correcta: Citando el estándar: 12.2.3 Los objetos temporales se destruyen como el último paso para evaluar la expresión completa (1.9) que (léxicamente) contiene el punto donde fueron creados. Y la plena expresión existe std::string utf8_text = qs.toUtf8().constData();Así que su afirmación no es correcta
Artyom

Eso es cierto: estaba pensando en const char * x = qs.ToUtf8 (). ConstData (). Aún así, ¿no es más fácil simplemente llamar a qs.toStdString ()?
Vitali

66
@Vitali No. Eso pierde caracteres no latinos1. Prueba esto: QString s = QString::fromUtf8("árvíztűrő tükörfúrógép ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP"); std::cout << s.toStdString() << std::endl; std::cout << s.toUtf8().constData() << std::endl;. El primero es incorrecto, el segundo es perfecto. Necesita un terminal utf8 para probar esto.
Notinlist

3
Por lo que vale, .toStdString()para mí siempre resulta en una infracción de acceso en el operador de canalización, independientemente de los QStringcontenidos (no latin1 o no). Esto está en Qt 4.8.3 / MSVC ++ 10 / Win 7.
Daniel Saner

269

Puedes usar:

QString qs;
// do things
std::cout << qs.toStdString() << std::endl;

Utiliza internamente la función QString :: toUtf8 () para crear std :: string, por lo que también es seguro para Unicode. Aquí hay documentación de referencia para QString.


73
A partir de Qt 5.0, QString::toStdString()ahora se utiliza QString::toUtf8()para realizar la conversión, por lo que las propiedades Unicode de la cadena no se perderán ( qt-project.org/doc/qt-5.0/qtcore/qstring.html#toStdString ).
Emile Cormier

Y si desea verificar el código fuente QString::toStdString, aquí está .
thuga

1
¿Cómo puedo probar para ver si realmente pierde la propiedad Unicode? ¿Lo hará el uso de caracteres Unicode (por ejemplo, decir de un idioma que no sea inglés)?
Yousuf Azad

35

Si su objetivo final es enviar mensajes de depuración a la consola, puede usar qDebug () .

Puedes usar como,

qDebug()<<string;que imprimirá el contenido en la consola .

De esta manera, es mejor que convertirlo std::stringsolo por depurar mensajes.


1
qDebug () sería mucho mejor, ya que admite más tipos de Qt.
Kamil Klimek

24
QString qstr;
std::string str = qstr.toStdString();

Sin embargo, si estás usando Qt:

QTextStream out(stdout);
out << qstr;

Había probado << qstr primero, antes de preguntar, pero no se compiló. Sin embargo, funciona con qstr.toStdString ().
agosto

2
No lo creo. Intentó std :: cout << qstr, no QTextString (stdout) << qstr;
Chris

18

Lo mejor sería sobrecargar el operador << usted mismo, de modo que QString pueda pasarse como un tipo a cualquier biblioteca que espere un tipo capaz de salida.

std::ostream& operator<<(std::ostream& str, const QString& string) {
    return str << string.toStdString();
}

3
¿Por qué los votos negativos, amigos? Es una exageración en mi caso, pero quién sabe, podría ser útil (para mí o para otra persona).
agosto

Me gusta esto porque Qt tiene la costumbre de cambiar la forma en que funcionan sus cadenas, y esto coloca la conversión en un solo lugar.
Den-Jason

12

Una alternativa a la propuesta:

QString qs;
std::string current_locale_text = qs.toLocal8Bit().constData();

podría ser:

QString qs;
std::string current_locale_text = qPrintable(qs);

Consulte la documentación de qPrintable , una macro que entrega un const char * de QtGlobal.


2
esto funciona incluso con un conjunto Qt-Build con -no-stl-Option. algo más de información
Senči



0
 QString data;
   data.toStdString().c_str();

incluso podría lanzar una excepción en el compilador VS2017 en xstring

 ~basic_string() _NOEXCEPT
        {   // destroy the string
        _Tidy_deallocate();
        }

la forma correcta (segura, sin excepción) es cómo se explica arriba de Artyom

 QString qs;

    // Either this if you use UTF-8 anywhere
    std::string utf8_text = qs.toUtf8().constData();

    // or this if you're on Windows :-)
    std::string current_locale_text = qs.toLocal8Bit().constData();

-1

Prueba esto:

#include <QDebug>
QString string;
// do things...
qDebug() << "right" << string << std::endl;

1
La pregunta es muy clara: convierta QString a std :: string, no para imprimirlo.
eyllanesc

@eyllanesc el texto de la pregunta dice "¿Cómo enviar el contenido de qstring a la consola?" , parece que OP supone que convertir a std :: string es la única forma. Realmente se hacen dos preguntas a la vez.
MM

@MM La pregunta parece poco clara ya que la pregunta en el título dice ¿Cómo convertir QString a std :: string? Tal vez sea un problema XY.
eyllanesc
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.