Zusammenhang von (w)ifstream mit locale und Encoding



  • Hiho,

    ich hatte gerade wieder "übliche" Probleme unter Windows, wo in der Darstellung bei Texten Umlaute und andere Nicht-ASCII-Zeichen Fehler auftraten. Die Texte kamen aus einer XML-Datei in UTF8, welche mit boost::serialization eingelesen werden per wifstream. Intern liegt dann alles als wstring in UTF16 vor.

    Meine Frage zielt nun auf den Zusammenhang zwischen den locale-Objekten und wie diese zur Konverierung bei den Streams genutzt werden. (w)ifstream nutzt ja standardmäßig das globale Locale-Objekt. Mit imbue kann ich ja auch ein lokales Objekt an den Stream geben.
    Ich kennen nun die locale-Objekte als "Konverter für nationale Anpassungen"; also das klassische Beispiel: das Komma als ',' oder '.' bei Fließkommazahlen. Inwieweit führt der locale-Mechanismus nun aber auch eine Anpassung beim Encoding durch?
    Sobald UTF8 ins Spiel kommt, greife ich eh meistens auf Boost zurück, da die Windows-Boardmittel eher schlecht als recht funktionieren. Und dort geht das Konvertieren ja meistens auch über die boost::locale-Objekte.

    Kann ich dem (w)ifstream auch irgendwie sagen, dass er überhaupt kein locale nutzen soll? Wenn ich eben wirklich die Rohdaten haben möchte.

    Also nochmal zusammenfassend gesagt, möchte ich gerne wissen, wie bei den std-streams die locale-Objekte eine Konvertierung zwischen verschiedenen Encodings beeinflussen. Das ist mir noch nicht ganz klar. Aber eben wichtig zu wissen, um das Ergebnis des Streams richtig weiterzunutzen. Vor allem, wenn dann auch noch boost mit reinkommt, welches ja auch wieder eigene Konvertierungen implizit oder explizit vornimmt.

    VG



  • Hm... zum Glück ist auf meinem System alles in utf-8. Ich finde den gesamten imbue-Krempel und alles, was irgendwie codecvt heißt, wahnsinnig undurchsichtig/kompliziert und habe es noch nie benutzt -> schau mal auf den Beispielcode hier: https://en.cppreference.com/w/cpp/locale/codecvt.

    Kannst du nicht vielleicht intern einfach alles in utf8 behalten und nur dort, wo du etwas anzeigen willst, umwandeln? Also kannst du das nicht so machen wie in https://utf8everywhere.org/#windows beschrieben?

    Ich würde also versuchen, so wenig wie möglich da mit den locales herumzuspielen.

    (sorry, habe keine Ahnung inwieeweit bzw. ob überhaupt dir das weiterhilft)



  • Die Undurchsichtigkeit versuche ich ja gerade zu lichten, indem ich mir anschaue, wie das genau funktioniert 🐕

    Ob ich beim Einlesen in UTF16 wandle, oder erst später, wenn ein API-Call kommt, der wchar will, ändert ja nix an der Tatsache, dass ich umwandeln muss.
    Für mein Problem habe ich eine Lösung gefunden. Ich wollte aber gerne verstehen, wie das mit den locales bei den Streams genau funktioniert. Daher mein Post hier.

    VG



  • Vielleicht helfen Dir die Links in dieser Antwort zu "Does (w)ifstream Support Different Encodings" weiter.


Log in to reply