[C++] Plattformunabhängiger stringstream

OP #4322817
Lesenswert?

Moin zusammen,

ich nutzte zur Serialisierung von Objekten std::stringstream. 
Funktioniert auch wunderbar. Aber ein stört mich daran noch: Das Format 
des erzeugten Strings hängt vom System locale setting ab. Damit kann ich 
keine Dateien erzeugen, die ohne Probleme auf andere Systeme übertragen 
werden können.

Dann dachte ich mir, ok ich geb ein fixes locale vor. Aber die locale 
Namen scheinen gemäß dieser Seite nicht standardisiert zu sein:
http://www.cplusplus.com/reference/locale/locale/locale/


Habt ihr ein Tipp wir ich am geschicktesten des erzeugten String 
plattformunabhängig bekomme?
#4323000
Lesenswert?

Die codierung UTF-8 wird von jeder ernstzunehmenden Platform 
unterstützt. Locale sind aber mehr als die Codierung, es gibt z.B. 
C.UTF-8 und en_US.utf-8, etc.

C.UTF-8 ist teil des POSIX standards, es sollte ihn fast überall geben, 
aber z.B. die sortierung von i,î und í nicht beieinander, sondern nach 
unicode wert, ich finde hier hat der POSIX standard versagt.

en_US.UTF-8 ist auf vielen Systemen vorhanden, aber nicht auf allen. 
Dafür werden i, î und í richtig sortiert.

Wenn die Sortierung einheitlich sein muss, und es nicht stört das i und 
î nicht intuitiv einsortiert werden, würde ich C.UTF-8 verwenden.
Wenn die Sortierung nicht einheitlich sein muss, würde ich versuchen die 
UTF-8 version des Systemlocales zu bekommen, ein fallback auf 
en_US.UTF-8 einbauen, und noch ein fallback auf C.UTF-8.

Ich glaube von den localen sind auch dinge wie Datumsformate abhängig. 
Ein riesen Chaos meiner meinung nach, ohne happyend.
Gast #4323037
Lesenswert?

Da D. schrieb:
> ich nutzte zur Serialisierung von Objekten std::stringstream.
> Funktioniert auch wunderbar. Aber ein stört mich daran noch: Das Format
> des erzeugten Strings hängt vom System locale setting ab. Damit kann ich
> keine Dateien erzeugen, die ohne Probleme auf andere Systeme übertragen
> werden können.

Dann serialisiere halt in ein gescheites Format und nicht blindlings in 
einen stringstream.
Gibt doch Serialisierungs-Libs wie Sand am Meer. Schlimmstenfalls halt 
nach XML oder JSON oder sowas.
Moderator #4323512
Lesenswert?

Da D. schrieb:
> Das Format des erzeugten Strings hängt vom System locale setting ab.
> Damit kann ich keine Dateien erzeugen, die ohne Probleme auf andere
> Systeme übertragen werden können.

Ich nehme an, dir geht es um solche Dinge wie Dezimaltrennzeichen (Punkt
oder Komma) u.ä.

Dateien, über die Daten zwischen mehreren Anwendungen übertragen werden,
sollten von diesen immer mit Locale "C" geschrieben und gelesen werden.
Das Default-Locale in C++ (wie auch in C) ist "C". Deswegen entstehen
normalerweise keine Probleme, solange man innerhalb der Programme
nirgends an den Locales herumpfuscht.

In C++ kann man das Locale für jeden Stream getrennt mit der Methode
imbue() einstellen. Tut man das nicht, wird als Locale das mit
std::locale::global() gesetzte globale Locale verwendet. Wurde das
globale Locale nicht explizit gesetzt, ist es "C".

Es ist in C++ i.Allg. unklug, das globale Locale zu setzen, da man damit
früher oder später oft auf die Nase fällt.

Falls du das globale Locale nicht selbst gesetzt hast, kann es sein,
dass das irgendeine übereifrige Bibliothek (bspw. ein GUI-Toolkit) für
dich gemacht hat, um dich zu ärgern. In diesem Fall hast du zwei
Möglichkeiten:

1. Du sagst der Bibliothek, dass sie das globale Locale nicht setzen
   soll (falls das möglich ist).

2. Du setzt für deinen stringstream das Locale mit imbue() explizit auf
   "C" oder std::locale::classic(), was beides dasselbe ist.
OP #4366655
Lesenswert?

Sorry, bin erst heute wieder dazu gekommen, mich um das Thema zu 
kümmern.

Yalu X. schrieb:
> Dateien, über die Daten zwischen mehreren Anwendungen übertragen werden,
> sollten von diesen immer mit Locale "C" geschrieben und gelesen werden.
> Das Default-Locale in C++ (wie auch in C) ist "C". Deswegen entstehen
> normalerweise keine Probleme, solange man innerhalb der Programme
> nirgends an den Locales herumpfuscht.

Danke, für die Aufklärung. Ich hatte das beim Lesen auf cplusplus.com 
anders interpretiert. Ich dachte, dass wenn "C" das default loacle ist, 
dass man damit wieder auf das locale, welches auf dem System eingestellt 
ist, zurück schalten kann. Aber so wie du schreibst, kann ich einfach 
zur Sicherheit auf "C" schalten, und müsste auf der sicheren Seite sein. 
Dankeschön!
OP #4366660
Lesenswert?

Nase schrieb:
> Dann serialisiere halt in ein gescheites Format und nicht blindlings in
> einen stringstream.
> Gibt doch Serialisierungs-Libs wie Sand am Meer. Schlimmstenfalls halt
> nach XML oder JSON oder sowas.

Die Antwort kann ich mir jetzt doch nicht verkneifen:
Ja, hast recht, ich sollte in ein gescheites Format serialisieren. 
Deswegen nehme ich XML. Aber Moment, XML ist ja ein Textformat, dazu 
muss ich ja Binärdaten in Strings verwandeln. Und dazu nehme ich, 
Überraschung, einen stringstream ;-)
Gast #4367736
Lesenswert?

Da D. schrieb:
> Nase schrieb:
>> Dann serialisiere halt in ein gescheites Format und nicht blindlings in
>> einen stringstream.
>> Gibt doch Serialisierungs-Libs wie Sand am Meer. Schlimmstenfalls halt
>> nach XML oder JSON oder sowas.
>
> Die Antwort kann ich mir jetzt doch nicht verkneifen:
> Ja, hast recht, ich sollte in ein gescheites Format serialisieren.
> Deswegen nehme ich XML. Aber Moment, XML ist ja ein Textformat, dazu
> muss ich ja Binärdaten in Strings verwandeln. Und dazu nehme ich,
> Überraschung, einen stringstream ;-)
Ja und nein.

XML ist im Prinzip schon ein Textformat, ja.
Schon mit XML Schema (vmtl. auch den meisten anderen Schemasprachen) 
kannst du aber gezielt Datentypen festlegen, so dass z.B. irgendwo ein 
"double" stehen soll. Damit ist dann auch schon vereinbart, wie der 
auszusehen hat[1]

Praktisch dürfte das wohl immer auf irgendwas ähnlich zu stringstream 
mit C-locale hinaus.


[1] http://www.w3.org/TR/xmlschema-2/#double
Gast #4367739
Lesenswert?

Soll heißen: XML ist zwar ein Textformat, aber es gibt in XML auch 
Datentypen.

Auch viele andere Serialisierungen erzeugen "Textformat". Aber auch dort 
ist dann festgelegt, wie die Datentypen zu Text werden und wie man vom 
Text wieder zum Datentyp kommt.
Genau das ist ja grad der Sinn von solchen Serialisierungen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren