2012-10-04 16 views
7

Ho iniziato a scrivere un'applicazione di manipolazione del testo molto semplice in Qt, senza una GUI. Il mio testo conteneva caratteri speciali, ma in qualche modo non ero in grado di stampare quei caratteri speciali, non importa quello che facevo. Ho poi notato che dopo aver aggiunto un'istanza QCoreApplication (che avevo precedentemente rimosso, perché pensavo che non avrei avuto bisogno), tutto ha funzionato esattamente come dovrebbe.Perché QString non tratta correttamente caratteri speciali, quando non è stata creata un'istanza di QCoreApplication?

Ecco il codice:

#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; 
} 

uscita con QCoreApplication (tutto funziona come dovrebbe):

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

uscita dopo aver commentato la riga, dove QCoreApplication definito (i caratteri speciali non sono mostrato più):

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

Nota, che già dopo aver chiamato qPrintabable(s), i caratteri speciali sono già stati rimossi. Ho verificato questo per sicurezza, che QDebug non è il problema.

Ho anche controllato se il file è realmente codificato in UTF-8.

Perché QString non tratta correttamente caratteri speciali, quando è stato istanziato il numero QCoreApplication?

+0

Yery domanda interessante ... Immagino che la ragione potrebbe essere all'interno di 'QTextCodec' o' QTextStream', ma potrei sbagliarmi. 'QDebug' usa un' QTextStream', ma come hai notato, 'qPrintable' (che è solo una scorciatoia per' .toLocal8Bit(). ConstData() ') rimuove magicamente i tuoi caratteri non-ascii, o inserisce un' '\ 0'', poiché questa è l'unica spiegazione per cui 'strlen' deve restituire 1. – leemes

+0

L'inserimento di'' \ 0'' non è il caso, poiché ho testato altre stringhe come '" aäa "', dove seguono altre lettere dopo un personaggio speciale. Non vengono rimossi. In altre parole, se 's' è' "aäa" ', l'output quando non si usa' QCoreApplication' è '" aa "'. – Misch

risposta

7

Dopo aver attraversato il codice sorgente di Qt, mi sono imbattuto in questo codice chiamato quando QCoreApplication è costruito:

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

In altre parole, su sistemi "Unix", il costruttore QCoreApplication sta facendo una chiamata a setlocale (trovati in locale.h), che viene utilizzato per impostare le impostazioni locali correnti del programma. Ciò in definitiva influisce sull'output da qDebug, che si basa su QTextStream, che in ultima analisi utilizza ciò che ritiene essere il locale definito dal sistema per creare il suo output.

Quando ho testato il codice su un sistema Linux, ho riscontrato lo stesso risultato che hai ottenuto. Su un sistema Windows, la creazione di commenti nella costruzione QCoreApplication non ha avuto alcun impatto sui risultati. Ho anche notato che la stampa della stringa originale tramite printf ha dato il risultato corretto indipendentemente dal fatto che sia stato costruito QCoreApplication.

+0

quindi questo è un bug o Qt specifica che si deve inizializzare un'applicazione 'Q (Core)' prima di usare altri componenti o classi Qt? – Misch

+0

@Misch Qt specifica le condizioni in base alle quali è necessario inizializzare un'applicazione Q (Core). Fare riferimento a http://qt-project.org/doc/qt-4.8/qcoreapplication.html. Questo particolare comportamento è documentato nella sezione "Impostazioni locali". –

Problemi correlati