[gelöst] utf-8 Encoding klappt bei manchen Zeichen nicht

Alles rund um die Programmierung mit Qt
Antworten
OscarWild
Beiträge: 54
Registriert: 19. Juni 2006 19:59

[gelöst] utf-8 Encoding klappt bei manchen Zeichen nicht

Beitrag von OscarWild »

Hallo,

ich stehe da vor einem kleinen Rätsel; ich versuche, den Text eines QTextDocument utf-8 codiert folgendermaßen in eine XML-Datei zu schreiben:

Code: Alles auswählen

QTextDocument  *doc;
QDomDocument  *xml;
.
.
QString s = doc->toPlainText().toUtf8();
xml->createTextNode(s);
.
.
Das klappt ganz gut für die meisten Zeichen inkl. Umlauten, die dann wie erwartet korrekt utf-8 kodiert in der Datei stehen ('äöü' -> 'äöü'), leider aber nicht für alle Zeichen. Z.B. das scharfe ß, das Eurozeichen, Vokale mit accent etc. werden stets als 'Ã?' kodiert, und sind damit unbrauchbar.

Ich benutze Qt 4.1.3 unter Windows; hat jemand ein ähnliches Problem, bzw. eine Lösung dafür? Mache ich da etwas falsch, oder ist das evtl. ein Bug?


Gruß + vielen Dank im Voraus für jegliche Hilfe
OscarWild
Zuletzt geändert von OscarWild am 20. Juni 2006 15:45, insgesamt 1-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Code: Alles auswählen

QString s = doc->toPlainText().toUtf8(); 
Was soll das denn? Lies nochmal die Doku was utf8() zurückbringt...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Re: utf-8 Encoding klappt bei manchen Zeichen nicht (ß, ¤, .

Beitrag von patrik08 »

OscarWild hat geschrieben:Umlauten, die dann wie erwartet korrekt utf-8 kodiert in der Datei stehen ('äöü' -> 'äöü'), leider aber nicht für alle Zeichen. Z.B. das scharfe ß, das Eurozeichen, Vokale mit accent etc. werden stets als 'Ã?' kodiert, und sind damit unbrauchbar.
Gruß + vielen Dank im Voraus für jegliche Hilfe
OscarWild
Ich kenne das problem ... dann wen der codec bei window nicht gesetzt ist... oder bei window xp MUI (multilanguage)

entweder sagt man bereits in der main ... dass alles utf8 sein soll

oder man speichert 100% utf8 ab .... oder libtidy mach es auch... ( post http://qtforum.de/forum/viewtopic.php?t=2216 )
Aber utf8 darstellen in einem qtextedit oder dessgleichen ... habe ich noch niee ... inbekommen.... nur auf dem file! mit vim von window oeffnen... zum sehen ... da andere programme vieleicht alles zu iso eu machen... wie bei firefox show source...


schade lauf unicode nicht ..... sonst koennte man jede sprache im xml abspeichern....

Code: Alles auswählen

bool Gui_Tidy::file_put_contents_utf8(QString fullFileName,QString xml)
{
QTextCodec *codecutf8 = QTextCodec::codecForMib(106);
/*QTextCodec *codeclatin1 = QTextCodec::codecForMib(4);*/

QString data = xml+"\n";
QFile f( fullFileName );
if ( f.open( QFile::WriteOnly | QFile::Text ) )
{
QTextStream sw( &f );
sw.setCodec(codecutf8);
sw << data;
f.close();
return true;
}
return false;
} 
OscarWild
Beiträge: 54
Registriert: 19. Juni 2006 19:59

Beitrag von OscarWild »

Christian81 hat geschrieben:Was soll das denn? Lies nochmal die Doku was utf8() zurückbringt...
Wie der Doku zu entnehmen ist:
toUtf8() returns a UTF-8 encoded 8-bit string. UTF-8 is a superset of ASCII that supports the entire Unicode character set through multibyte sequences.

Genau das, was ich möchte. Und ja: der Rückgabewert ist ein QByteArray, das sich aber in einen QString konvertieren lässt, den QDomDocument::createTextNode() nun mal als Datentyp erwartet...

@Christian81: Was für ene Alternative würdest Du denn vorschlagen?

Evtl. sollte ich mal das QByteArray Byte für Byte untersuchen, ggf. geht erst der Cast in den QString schief.

Es sollte doch ein tagtäglicher Anwendungsfall sein, QStings utf8-codiert irgendwo zu verstauen...

@patrik08: Danke für den Tipp. Die Sache mit QTextStream habe ich schon gefunden, aber ich bin möchte die XML-Datei nicht manuell generieren (das gesamte System ist bereits auf QDomDocument ausgelegt :( )
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Du machst es an der falschen Stelle - ein QString ist *immer* locale independent. D.h. wenn die Funktionen einen QString will, musst Du ihr den auch geben. Allerdings wird der String vorher mit dem .toUtf8() kaputt gemacht (Es wird ein QString str = QString::fromAscii(doc->toPlainText().toUtf8()) draus - also einfach nur Datenmüll).
Übergib der Funktion einfach doc->toPlainText().toUtf8() und gut ist. Wenn du das Dokument dann speicherst sollte natürlich http://doc.trolltech.com/4.1/qdomdocument.html#toString oder gleich http://doc.trolltech.com/4.1/qdomdocume ... oByteArray benutzt werden.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
OscarWild
Beiträge: 54
Registriert: 19. Juni 2006 19:59

Beitrag von OscarWild »

Die richtige Löung ist eine Kombination aus Euren Hinweisen :-)
patrik08 hat geschrieben:

Code: Alles auswählen

QTextStream sw( &f );
sw.setCodec(codecutf8);
Christian81 hat geschrieben:Allerdings wird der String vorher mit dem .toUtf8() kaputt gemacht
Jein. Wäre QTextStream Codec-frei, wäre der Aufruf von .toUtf8() notwendig; offensichtlich verstümmelt QTextStream aber mache Zeichen, wenn man den Codec nicht explizit vorgibt.
Setze ich utf-8 für den QTextStream, wie von patrik08 vorgeschlagen, entfällt das .toUtf8() und alles ist in Butter, die Zeichen befinden sich jetzt richtig codiert in der Datei :-)


Vielen Dank für Eure Hilfe!


Ach ja: zwar unerheblich für mein Problem, aber generell
Christian81 hat geschrieben:Übergib der Funktion einfach doc->toPlainText().toUtf8() und gut ist.
Das wäre sinnlos. createTextNode() würde das QByteArray aus .toUtf8() zwangsläufig in einen QString casten.
Temporäre Variablen erzeugen allenfalls etwas Overhead, falls sie der Compiler nicht optimiert. :wink:
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Wenn ihr meint...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag von patrik08 »

Wenn du jede welt sprache schreiben kannst in deine xml datei dann ist es gut....

Mein pc ist voll auf iso codec eu.... ..

das resultat is jedoch unicode! fuer jeden pc.....

http://ciz.ch/svnciz/dialog_qt/qt4_a/vi ... /qtidy.cpp
http://ciz.ch/svnciz/dialog_qt/qt4_a/vi ... lt/qtidy.h


die tidy config setzen und putzen.... geht prima schnell!!
und sauber formatiert....

die 300kb statische libs ist ja federleicht... und ohne dll...

Code: Alles auswählen

/* prepare config tidy config file xml clean */
bool QTidy::SetUp_xml()
{
    qDebug() << "### load config xml ....  ";
    bool ok;
    tidiconfigfile.clear();
    tidiconfigfile.append("input-xml: yes");
    tidiconfigfile.append("clean: yes");
    tidiconfigfile.append("char-encoding: ascii");
    tidiconfigfile.append("output-xml: yes");
    tidiconfigfile.append("hide-comments: yes");
    tidiconfigfile.append("numeric-entities: yes");
    tidiconfigfile.append("add-xml-space: yes");
    QString configtotsl = tidiconfigfile.join("\n");
    ok = file_set_config(configtotsl);   /* TIDY_CONF */
    if (ok) {
         QByteArray configfileti = TIDY_CONF.toAscii();
         status = tidyLoadConfig( doc, configfileti.data() );  /* http://ch2.php.net/manual/de/function.tidy-load-config.php */
        if ( status != 0 ) {
         ErrorMSG ="Not possibel to load Config File!";
         return false;
        } else {  
        return true;
        } 
    } else {
      ErrorMSG ="Not possibel to load Config File!";
     return false;  
    }  
}


/* prepare config tidy config file xhtml clean */
bool QTidy::SetUp_xhtml()
{
    qDebug() << "### load config. xhtml ...  ";
    bool ok;
    tidiconfigfile.clear();
    tidiconfigfile.append("output-xhtml: yes");
    tidiconfigfile.append("clean: yes");
    tidiconfigfile.append("wrap: 550");
    tidiconfigfile.append("indent-spaces: 1");
    tidiconfigfile.append("char-encoding: ascii");
    tidiconfigfile.append("wrap-attributes: yes");
    tidiconfigfile.append("doctype: yes");
    tidiconfigfile.append("hide-comments: yes");
    tidiconfigfile.append("numeric-entities: yes");
    tidiconfigfile.append("drop-proprietary-attributes: no");
    tidiconfigfile.append("show-body-only: yes");  /* only body checks */
    QString configtotsl = tidiconfigfile.join("\n");
    ok = file_set_config(configtotsl);   /* TIDY_CONF */
    if (ok) {
         QByteArray configfileti = TIDY_CONF.toAscii();
         status = tidyLoadConfig( doc, configfileti.data() );  /* http://ch2.php.net/manual/de/function.tidy-load-config.php */
        if ( status != 0 ) {
         ErrorMSG ="Not possibel to load Config File!";
         return false;
        } else {  
        return true;
        } 
    } else {
      ErrorMSG ="Not possibel to load Config File!";
     return false;  
    }  
}

Antworten