Ich habe Code, der Binärdateien manipuliert, indem er fstream mit dem gesetzten binären Flag verwendet und die unformatierten E / A-Funktionen liest und schreibt. Dies funktioniert auf allen Systemen, die ich je benutzt habe (die Bits in der Datei sind genau wie erwartet), aber das sind im Grunde alle US-Englisch. Ich habe mich gefragt, ob diese Bytes möglicherweise von einem Codecvt auf einem anderen System geändert werden.
Es klingt wie im Standard, dass die Verwendung unformatierter E / A sich genauso verhält wie das Einfügen von Zeichen in den Stream mit sputc / sgetc. Dies führt zu den Überlauf- oder Unterlauffunktionen im aufgerufenen streambuf, und es hört sich so an, als würden diese zu einem Codecvt führen (siehe beispielsweise 27.8.1.4.3 im C ++ - Standard). Für basic_filebuf ist die Erstellung dieses Codecvt in 27.8.1.1.5 angegeben. Das sieht so aus, als ob die Ergebnisse davon abhängen, was basic_filebuf.getloc () zurückgibt.
Also, meine Frage ist, kann ich annehmen, dass ein Character-Array, das mit ofstream.write auf einem System geschrieben wurde, wörtlich mit ifstream.read auf einem anderen System wiederhergestellt werden kann, egal welche Locale-Konfiguration eine Person auf ihrem System verwendet ? Ich würde die folgenden Annahmen treffen:
Wenn das Standardgebietsschema bei einigen Systemkonfigurationen nicht garantiert ist (ich weiß nicht, Arabisch oder so), was ist dann der beste Weg, Binärdateien mit C ++ zu schreiben?
Unter Windows sollte es in Ordnung sein, aber auf anderen Betriebssystemen sollten Sie auch die Zeilenenden überprüfen (genauso wie die Sicherheit). Das Standard-C / C ++ - Gebietsschema ist "C", was abhängig von der Ländereinstellung des Systems nicht ist.
Dies ist keine Garantie. Wie Sie wissen, variieren C / C ++ - Compiler und ihre Zielrechner stark. Sie warten also auf Probleme, wenn Sie all diese Annahmen beibehalten. Es gibt einen vernachlässigbaren Overhead für das Ändern des Gebietsschemas, es sei denn, Sie versuchen, es in Hunderten von Sekunden pro Sekunde zu machen.
Wenn Sie das binäre Flag gesetzt haben, wird alles, was Sie schreiben, wörtlich in die Datei geschrieben. Keine Conversions Wie Sie die Bytes interpretieren, liegt an Ihnen (und möglicherweise an der Ländereinstellung).
Noch eine Sache: Es gibt eine Möglichkeit zu brechen an verschiedenen Orten. Wenn Ihre Datenquelle beispielsweise binäre Daten basierend auf dem Gebietsschema erstellt hat (und das Format dieser Daten sich je nach Gebietsschema ändern würde - das ist eine schlechte Idee, btw). Dies würde beim Laden von Daten auf Maschinen mit unterschiedlichen Ländereinstellungen zu Problemen führen. Dies ist jedoch ein Konstruktionsfehler.
Wenn Sie nur Standarddatentypen / Strukturen verwenden, die dasselbe Format / Layout haben, egal in welchem Gebietsschema sie erstellt wurden, sollte alles in Ordnung sein.
Danke für die Hilfe. Ich dachte nur, es könnte hilfreich sein, einige zusätzliche Informationen darüber zu veröffentlichen, die nicht in einen Kommentar passen würden.
Das Standardgebietsschema für C ++ - Programme ist immer das Gebietsschema "C" ( Ссылка ). Wenn dies das einzige in Ihrem Programm verwendete Gebietsschema ist, bedeutet dies, dass das Verhalten nicht von der jeweiligen Gebietsschema-Konfiguration des Computers abhängt, auf dem es ausgeführt wird. Es bedeutet auch, dass unformatierte I / O für einen Char keine Code-Konvertierung unterzogen wird (wchar_t könnte jedoch eine andere Geschichte sein). Dies bedeutet, dass Lesen und Schreiben (angesichts der Annahmen in der Frage) ermöglichen sollte, dass Binärdaten unverändert wiederhergestellt werden können.
(aus dem Lesen der Dokumentation) Sie können das Gebietsschema der Anwendung global auf den Systemstandard einstellen, indem Sie setlocale (LC_ALL, "") aufrufen, was bedeutet, dass die von diesem Punkt erstellten Streams das Standardgebietsschema des Systems verwenden. Um es auf das Gebietsschema "C" zurückzusetzen, können Sie setlocale (LC_ALL, "C") aufrufen, was bedeutet, dass dies für die in Zukunft erstellten Streams verwendet wird. Sie können auch angeben, dass "C" local für einen Stream verwendet werden soll, der bereits durch Aufrufen von stream.imbue (locale :: classic ()) erstellt wurde.