Seite 1 von 1
[gelöst] utf-8 Encoding klappt bei manchen Zeichen nicht
Verfasst: 19. Juni 2006 20:19
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
Verfasst: 20. Juni 2006 09:39
von Christian81
Was soll das denn? Lies nochmal die Doku was utf8() zurückbringt...
Re: utf-8 Encoding klappt bei manchen Zeichen nicht (ß, ¤, .
Verfasst: 20. Juni 2006 09:58
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;
}
Verfasst: 20. Juni 2006 12:17
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

)
Verfasst: 20. Juni 2006 12:48
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.
Verfasst: 20. Juni 2006 15:44
von OscarWild
Die richtige Löung ist eine Kombination aus Euren Hinweisen
patrik08 hat geschrieben:
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.

Verfasst: 20. Juni 2006 16:09
von Christian81
Wenn ihr meint...
Verfasst: 20. Juni 2006 19:01
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;
}
}