8

バイナリ フラグが設定された fstream を使用し、フォーマットされていない I/O 関数の読み取りと書き込みを使用して、バイナリ ファイルを操作するコードがあります。これは、私が今まで使用したすべてのシステムで正しく動作します (ファイル内のビットは正確に期待どおりです) が、基本的にすべて米国英語です。これらのバイトが別のシステムの codecvt によって変更される可能性について疑問に思っていました。

標準では、フォーマットされていない I/O を使用することは、sputc/sgetc を使用してストリームバッファに文字を入れるのと同じように動作すると述べているようです。これらは、streambuf のオーバーフロー関数またはアンダーフロー関数が呼び出されることにつながり、一部の codecvt を通過するように思えます (たとえば、c++ 標準の 27.8.1.4.3 を参照)。basic_filebuf の場合、この codecvt の作成は 27.8.1.1.5 で指定されています。これにより、結果は basic_filebuf.getloc() が返すものに依存するように見えます。

それで、私の質問は、あるシステムで of​​stream.write を使用して書き出された文字配列が、別のシステムで ifstream.read を使用して逐語的に復元できると仮定できますか? 私は次の仮定をします:

  1. プログラムはデフォルトのロケールを使用しています (つまり、プログラムはロケール設定自体をまったく変更していません)。
  2. どちらのシステムもCHAR_BIT 8を持ち、各バイト内で同じビット順序を持ち、ファイルをオクテットとして保存するなど.
  3. ストリーム オブジェクトにはバイナリ フラグが設定されています。
  4. この段階では、エンディアンの違いについて心配する必要はありません。配列内のいずれかのバイトがマルチバイト値として解釈される場合、エンディアン変換は後の段階で必要に応じて処理されます。

デフォルトのロケールが、一部のシステム構成で変更されていないものを通過することが保証されていない場合 (アラビア語かどうかはわかりません)、C++ を使用してバイナリ ファイルを作成する最良の方法は何ですか?

4

3 に答える 3

1

バイナリ フラグが設定されている場合、書き込む内容はすべてファイルに逐語的に書き込まれます。変換なし。バイトをどのように解釈するかはあなた次第です (そしておそらくロケールも)。

もう 1 つ: 異なるロケールでは破損する可能性があります。たとえば、データ ソースがロケールに基づいてバイナリ データを作成した場合 (そして、このデータの形式はロケールに応じて変化します - これは悪い考えです)。これにより、異なるロケールのマシンにデータをロードするときに問題が発生します。これは設計ミスですが。

作成されたロケールに関係なく、同じ形式/レイアウトを持つ標準のデータ型/構造を使用するだけであれば、すべて問題ありません。

于 2009-12-03T00:04:39.600 に答える
0

Windows では問題ありませんが、他の OS では行末も確認する必要があります (安全のため)。デフォルトの C/C++ ロケールは「C」で、システムのロケールに依存しません。

これは保証ではありません。ご存知のように、C/C++ コンパイラとそのターゲット マシンは大きく異なります。したがって、これらすべての仮定を維持すると、問題が発生するのを待っています。1 秒間に何百回もロケールを変更しようとしない限り、ロケールの変更によるオーバーヘッドはごくわずかです。

于 2009-12-02T08:40:46.350 に答える