2012-10-04 2 views
7

Ich begann eine sehr einfache Textmanipulationsanwendung in Qt zu schreiben, ohne GUI. Mein Text enthielt Sonderzeichen, aber irgendwie konnte ich diese Sonderzeichen nicht drucken, egal was ich tat. Ich bemerkte dann, dass nach dem Hinzufügen einer QCoreApplication Instanz (die ich zuvor entfernt hatte, weil ich dachte, ich würde es nicht brauchen), alles funktioniert so wie es sollte.Warum behandelt QString Sonderzeichen nicht korrekt, wenn keine QCoreApplication instanziiert wurde?

Hier ist der Code:

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

Ausgang mit QCoreApplication (alles funktioniert, wie es sollte):

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

Ausgang nach der Zeile auskommentieren, wo QCoreApplication (Sonderzeichen definiert wird, sind nicht gezeigt mehr):

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

Beachten Sie, dass Bereits nach dem Aufruf sind die Sonderzeichen bereits entfernt. Ich testete dies um sicher zu sein, dass QDebug nicht das Problem ist.

Ich überprüft auch, ob die Datei wirklich in UTF-8 codiert ist.

Warum behandelt QString Sonderzeichen nicht korrekt, wenn kein QCoreApplication instanziiert wurde?

+0

Yery interessante Frage ... Ich denke, dass der Grund in "QTextCodec" oder "QTextStream" sein könnte, aber ich könnte falsch liegen. 'QDebug' verwendet einen' QTextStream', aber wie Sie bemerkt haben, entfernt das 'qPrintable' (das nur eine Abkürzung für' .toLocal8Bit(). ConstData() 'ist) bereits magische ASCII-Zeichen oder fügt ein' 'ein '\ 0'', da dies die einzige Erklärung ist, warum' strlen '1 zurückgeben soll. – leemes

+0

Das Einfügen von' '\ 0'' ist nicht der Fall, da ich andere Strings als 'ääa'' getestet habe, wo andere Buchstaben folgen nach einem speziellen Charakter. Sie werden nicht entfernt. Mit anderen Worten, wenn "s" "aäa" ist, ist die Ausgabe, wenn "QCoreApplication" nicht verwendet wird, "aa". – Misch

Antwort

7

Nach Qt-Quellcode durchlaufen, ich auf diesem Code aufgerufen gestolpert, wenn QCoreApplication aufgebaut ist:

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

Mit anderen Worten, auf „Unix“ Systemen wird der QCoreApplication Konstruktor einen Aufruf an setlocale machen (gefunden in locale.h), mit dem das aktuelle Gebietsschema des Programms festgelegt wird. Dies wirkt sich letztendlich auf die Ausgabe von qDebug aus, die auf QTextStream basiert, die letztendlich das System verwendet, das sie für das systemdefinierte Gebietsschema zum Erstellen der Ausgabe hält.

Als ich Ihren Code auf einem Linux-System getestet habe, bin ich auf dasselbe Ergebnis gestoßen wie Sie. Auf einem Windows-System hatte das Auskommentieren der QCoreApplication Konstruktion keinen Einfluss auf die Ergebnisse. Ich bemerkte auch, dass das Ausdrucken der ursprünglichen Zeichenfolge über printf das richtige Ergebnis unabhängig davon ergab, ob QCoreApplication erstellt wurde.

+0

also ist das ein Fehler, oder gibt Qt an, dass man eine 'Q (Core) Application' initialisieren muss, bevor man andere Qt-Komponenten oder -Klassen benutzt? – Misch

+0

@Misch Qt gibt die Bedingungen an, unter denen eine Q (Core) -Anwendung initialisiert werden muss. Siehe http://qt-project.org/doc/qt-4.8/qcoreapplication.html. Dieses spezielle Verhalten ist im Abschnitt "Gebietsschemaeinstellungen" dokumentiert. –

Verwandte Themen