string.replace und Umlaute



  • Nein keine Frage wie ersetzte ich Umlaute in strings.

    Ich lese eine xml Datei als string ein.
    Dann ersetz ich ein bestimmtes Wort im string mit einem anderem.
    Danach wird aus dem string eine andere xml Datei erzeugt.

    Das ganze funktioniert ohne Probleme bis Umlaute ins Spiel kommen.
    In der xml Datei sind schon Umlaute drin und die machen keine Probleme.
    Probleme gibt es aber wenn ich z.B. "Name" mit "Müller" ersetze.
    Möchte ich nun die xml Datei verwenden bekomm ich den Fehler "Im Textinhalt wurde ein ungültiges Zeichen gefunden. Fehler beim Bearbeiten der Ressource 'file:///...." und die Datei kann nicht angezeigt werden.

    Öffne ich die Datei im Texteditor steht an der richtigen Stelle "Müller".
    Lösche ich das "ü" raus und speicher ab ist die Datei wieder verwendbar.
    Öffne ich die Datei und schreibe von Hand "Müller" rein und speicher sie, ist sie auch normal verwendbar. Nur wenn ich ein Umlaut mit replace einfüge gibt es den Ärger.

    Hier mal ein Beispiel als Code.

    ifstream in;   //Einzulesene Datei
      ofstream out;  //Geschriebene Datei
    
      //Öffnet die content.xml Datei und liest sie zeilenweise in einen String
      in.open("content.xml");
      string gesamt;
      for( string s; getline(in, s); )
        gesamt += s;
      in.close();
    
      //Ersetzt "Name" durch "Müller"
      gesamt.replace(8333, 4, "Müller");
    
      //Schreibt den string in eine neue xml Datei
      out.open("neuecontent.xml");
      out << gesamt;
      out.close();
    

    Die xml Datei schaut so aus:

    <?xml version="1.0" encoding="UTF-8" ?>
    .
    .
    .
    <text:p text:style-name="P2">Name</text:p>
    .
    .
    .
    

    Liegt es vielleicht am encoding UTF-8? Aber das bezieht sich ja eigentlich nur darauf wie der Inhalt angezeigt werden soll.
    Weiß einer Rat?

    Keine Umlaute in die xml Datei zu schreiben ist leider keine akzeptable Lösung.



  • Hallo,

    std::strings sind nicht dafür gemacht, mit Umlauten umzugehen. Verwende hierzu entweder std::wstring oder (besser) eine Alternative deines Frameworks, z.B. der MFC, WinAPI oder der glib(mm), QT usw.

    MfG

    GPC



  • Hmmm, das ist mein erstes Windowsprogramm mit dem C++ Builder 6.

    Ich habe string genommen, weil die replace Funktion so prima gepasst hat.
    Diese Zeile aus dem Code von oben hab ich nur als vereinfachtes Beispiel genommen.

    gesamt.replace(8333, 5, "Müller");
    

    Normalerweise habe ich zwei vector<string>. Einen vector mit den zu suchenden Wörtern und einen mit den zu ersetzenden Wörtern.

    gesamt.replace(gesamt.find(SuchenListe[i]), SuchenListe[i].length(), ErsetzenListe[i]);
    

    Später soll dann der string in einer Schleife durchsucht und die Wörter ersetzt werden.

    Was für eine Alternative die mit dem C++ Builder 6 realisierbar ist empfiehlst du mir?



  • Oniko schrieb:

    Was für eine Alternative die mit dem C++ Builder 6 realisierbar ist empfiehlst du mir?

    Puh, Borland, da gibt es AFAIK den TString und den AnsiString. Probier's aus. Ich kenn mich da leider nicht aus, aber oben gibt es ein Board, welches sich mit dem Borland befasst.

    Edit: das hier könnte dir helfen, ansonsten im BCB Forum nach *Umlauten* oder *Unicode* suchen.

    MfG

    GPC



  • Danke für die Antwort.
    Die in dem anderem Beitrag verlinkten Unicode Komponenten für den Borland Builder muss ich mir noch genauer ansehen.

    Ich habe nun komplett auf string und vector<string> verzichtet und es mit AnsiString und TStringList versucht.

    Leider mit dem selben Ergebnis.

    Speicher ich die TStringList als xml Datei (SaveToFile())wird die Datei fehlerhaft und die Umlaute nicht angezeigt.



  • Oniko schrieb:

    Danke für die Antwort.
    Die in dem anderem Beitrag verlinkten Unicode Komponenten für den Borland Builder muss ich mir noch genauer ansehen.

    Ich habe nun komplett auf string und vector<string> verzichtet und es mit AnsiString und TStringList versucht.

    Leider mit dem selben Ergebnis.

    Speicher ich die TStringList als xml Datei (SaveToFile())wird die Datei fehlerhaft und die Umlaute nicht angezeigt.

    Okay, dann kann ich dich nur ans BCB Forum weiter oben verweisen und dir mit den Klassen aus dem Link viel Glück wünschen. Tut mir leid, aber ich kenne mich da mit Borland zu wenig aus 😞

    MfG

    GPC



  • Was wird denn angezeigt, wenn du die Datei mit dem replace'ten "Müller" im Texteditor öffnen willst? Möglicherweise gibt es ja ein Problem mit den Unterschieden zwischen ASCII- und ANSI-Codes (die Zeichen über '\x7F' werden je nach Zeichensatz unterschiedlich interpretiert)

    *nachgeguckt hat*
    UTF-8 codiert Erweiterungszeichen durch 2 oder mehr Bytes, d.h. du mußt statt der Umlaute die entsprechenden Hex-Sequenzen angeben (z.B. "ä" = "\xC3\xA4" - siehe Wikipedia-Beispiel).



  • Also um XML-Dateien zu verarbeiten, sollte man doch eine XML-Parser benutzen. Denn da braucht man sich um das UTF-8 Thema nicht weiter zu kümmern... zumindest erwartet man das von einer vernünftigen XML-Parser-Library. 😉

    std::string ist auch etwas unglücklich für UTF-8, da kann man dann genauso gut std::vector<char> nehmen, wäre genauso uneffektiv.

    Leider gibts in ISO-C++ keinen UTF-8 Support. std::string ist eine reine ASCII-String-Klasse. Deshalb haben ja gtkmm, qt und wxwidgets eigene Stringklassen. Man kann höchstens std::wstring benutzen, das wäre dann ähnlich UTF-16. Dazu müsste man aber eine Funktion haben, die UTF-8 Codes in wstrings konvertiert und beim rausschreiben dann wieder von wstring nach UTF-8.

    Fazit: man kommt um eine vernünftige XML-Library nicht rum, um sich den Ärger zu sparen.



  • Artchi schrieb:

    Also um XML-Dateien zu verarbeiten, sollte man doch eine XML-Parser benutzen. Denn da braucht man sich um das UTF-8 Thema nicht weiter zu kümmern... zumindest erwartet man das von einer vernünftigen XML-Parser-Library. 😉

    Wie soll denn die XML-Bibliothek mit dem Encoding des Editors umgehen? Die String-Literale nach Sonderzeichen durchsuchen und einfach entsprechend der aktuellen Codepage konvertieren? Ich glaube die Konvertierung zwischen bestimmten Encodings sollte extra, d. h. unabhängig von der XML-Lib, behandelt werden, so wie es z. Bsp. im .NET-Framework durch System::Text::Encoding realisiert ist.



  • CStoll schrieb:

    Was wird denn angezeigt, wenn du die Datei mit dem replace'ten "Müller" im Texteditor öffnen willst? Möglicherweise gibt es ja ein Problem mit den Unterschieden zwischen ASCII- und ANSI-Codes (die Zeichen über '\x7F' werden je nach Zeichensatz unterschiedlich interpretiert)

    *nachgeguckt hat*
    UTF-8 codiert Erweiterungszeichen durch 2 oder mehr Bytes, d.h. du mußt statt der Umlaute die entsprechenden Hex-Sequenzen angeben (z.B. "ä" = "\xC3\xA4" - siehe Wikipedia-Beispiel).

    Danke für den Hinweis.
    Im Texteditor wird dann nur "Mller" angezeigt statt "Müller".
    Wenn ich die Umlauet als UTF-8 hexadezimal angebe scheint es zu gehen.

    //Ersetzt im String gesamt "Name" durch "Müller"
    gesamt.replace(8333, 5, "M\xc3\xbcller");
    

    Das "ü" erscheint nun in der xml Datei und es kommt kein Fehler mehr. 🙂

    Demnach wäre es ja möglich den vector<string> mit meinen einzufügenden Strings auf Umlaute zu durchsuchen und diese mit dem jeweiligem UTF-8 Hexwert zu ersetzen.

    Notlösung wäre ein XML Parser.
    Weiß jemand sicher, dass die UTF-8 unterstützung beim erzeugen eines xml Dokumentes wirklich gegeben ist?


Anmelden zum Antworten