2012-10-04 55 views
7

Empecé a escribir una aplicación de manipulación de texto muy básica en Qt, sin una GUI. Mi texto contenía caracteres especiales, pero de alguna manera no pude imprimir esos caracteres especiales, sin importar lo que hice. Entonces noté que después de agregar una instancia de QCoreApplication (que había eliminado previamente, porque pensé que no la necesitaría), todo funcionó como debería.¿Por qué QString no trata los caracteres especiales correctamente cuando no se ha creado una instancia de QCoreApplication?

Aquí está el código:

#include <QCoreApplication> 
#include <QString> 
#include <QDebug> 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 

    QString s(QString::fromUtf8("aä\xc3\xa4")); // aää 

    qDebug() << s; 
    qDebug() << s.toAscii(); 
    qDebug() << s.toLatin1(); 
    qDebug() << s.toUtf8(); 
    qDebug() << s.toLocal8Bit(); 
    qDebug("%s", qPrintable(s)); 

    qDebug("%i", s.length()); 
    qDebug("%i", strlen(qPrintable(s))); 

    return 0; 
} 

salida con QCoreApplication (todo funciona como debería):

"aää" 
"aää" 
"aää" 
"aää" 
"aää" 
aää 
3 
5 

de salida después de comentar la línea, donde QCoreApplication se define (caracteres especiales no son se muestra más):

"a" 
"a" 
"a" 
"a" 
"a" 
a 
3 
1 

Nota, eso ya después de llamar al qPrintabable(s), los caracteres especiales ya se eliminaron. He probado esto para estar seguro, que QDebug no es el problema.

También verifiqué si el archivo está realmente codificado en UTF-8.

¿Por qué QString no trata los caracteres especiales correctamente cuando no se ha creado una instancia de QCoreApplication?

+0

Yery pregunta interesante ... Supongo que la razón podría estar dentro de 'QTextCodec' o' QTextStream', pero podría estar equivocado. 'QDebug' usa un' QTextStream', pero como habrás notado, el 'qPrintable' (que es solo una abreviatura de' .toLocal8Bit(). ConstData() ') ya elimina mágicamente tus caracteres no ascii, o inserta un' '\ 0'', ya que esta es la única explicación de por qué 'strlen' debería devolver 1. – leemes

+0

Insertar'' \ 0'' no es el caso, ya que he probado otras cadenas como '" aaa '', donde siguen otras letras después de un personaje especial. Ellos no son eliminados. En otras palabras, si 's' es' "aaa' ', la salida cuando no se usa' QCoreApplication' es '" aa "'. – Misch

Respuesta

7

Después de pasar por el código fuente de Qt, me encontré con este código de llamada cuando QCoreApplication se construye:

#ifdef Q_OS_UNIX 
    setlocale(LC_ALL, "");    // use correct char set mapping 
    qt_locale_initialized = true; 
#endif 

En otras palabras, en los sistemas de "Unix", el QCoreApplication constructor está haciendo una llamada a setlocale (que se encuentra en locale.h), que se utiliza para establecer la configuración regional actual del programa. En última instancia, esto afecta a la salida de qDebug, que se basa en QTextStream, que finalmente utiliza lo que cree que es la configuración regional definida por el sistema para crear su salida.

Cuando probé su código en un sistema Linux, encontré el mismo resultado que usted. En un sistema Windows, comentar la construcción QCoreApplication no tuvo ningún impacto en los resultados. También noté que imprimir la cadena original a través de printf dio el resultado correcto independientemente de si se construyó QCoreApplication.

+0

¿es esto un error o Qt especifica que se debe inicializar una aplicación 'Q (Core)' antes de usar otras clases o componentes de Qt? – Misch

+0

@Misch Qt especifica las condiciones bajo las cuales se debe inicializar una aplicación Q (Core). Consulte http://qt-project.org/doc/qt-4.8/qcoreapplication.html. Este comportamiento en particular está documentado en la sección "Configuración de configuración regional". –

Cuestiones relacionadas