C++ で非 ASCII ファイルを読み書きする方法についての参照が見つかりません。
ファイル内の情報を緻密なパターンとマークアップで表現しながらファイルフォーマットを作成したいのですが、基本的にfstream
はテキストファイルしか作成できません。この目的では、テキスト モードまたはバイナリ モードは実際には関係ありません。結果は常に ASCII ファイルです。
テキストエディタで単純に解析できず、独自の定義があるようなファイルをバイトごとに書き込む方法は?
必要なのは、ファイルをバイトストリームとして扱うことです。これは、read() と write() を使用して実現できます。ファイルがテキストでない場合、ファイルを直接処理する場合、通常のストリーム演算子<< >>
は使用できません。
通常、ストリーム オペレータをオーバーロードするために、read()/write() の上に独自の読み取り/書き込み関数を作成します。
別のアプローチは、レコードのレイアウトで構造体を作成し、それを fread()/fwrite() で使用する fread() fwrite() を使用することです。
typedef struct
{
short id;
char name[64];
} rec;
rec A;
fread( &A, sizeof(A), 1, fp );
「エディタで読む」ことができないファイルがある場合、それは単にデータがテキスト形式で保存されていないことを意味します。他の人が言ったように、C と C++ では、ファイルのテキスト形式とバイナリ形式の間に大きな違いはありません。変換 (行末など) と規則 (たとえば、ファイルの終わりを文字でマークできるため) に関するいくつかの単純な規則にすぎません。ファイルの長さはブロック単位ですが、テキスト ファイルに 512 バイト ブロックの正確な倍数は必要ないため、CTRL-D または CTRL-Z を使用してファイルの終わりをマークします)。バイナリモードでは、「なんでもあり」。
多くの点で、バイナリ ファイルは、データが何を表しているかをコンパイラが認識できないという点で、テキスト ファイルと非常によく似ています。テキスト ファイルに次のものが含まれている場合:
12345 Glurg 12.88
1Ab9Z Flarf 6.89
最初の列が製品 ID であると判断するのはプログラムです (最初の行を読むと、整数であると思うでしょうが、2 番目の列は整数として表すことができないため、文字列として格納する必要があります)。 )、二番目は商品名、三番目は価格かな?それとも重さ?(キロ、グラム、ポンド、トン?)
したがって、バイナリ ファイルの場合と同様に、プログラムは各バイトまたはバイトの集まりが何を意味するかを知る必要があります。
よく知られた形式 (PDF、Excel スプレッドシートなど) の場合、その形式を処理するライブラリが無料または有料で利用できる場合があります。そうでない場合は、ファイル自体のフォーマットの適切な説明が必要であり、上記の読み取り/書き込みまたはストリームバッファ機能を使用してください。
フォーマットが独自のものである場合、または少なくとも超移植性がない場合は、適切なフォーマットを持つ構造体を形成し、それらの構造体を 1 つの読み取り操作として読み取り、1 つの書き込み操作として書き込むことができる場合があります。形式が移植可能であることを意図している場合、それはおそらく機能しません。また、構造体を読み書きする方法は移植性が低いことに注意してください。これは、コンパイラが構造体にギャップを入れる可能性があるためです。これは、マシンのアーキテクチャによって異なります。
C++ はバイナリ形式を直接サポートしていません。主な理由は、一般的に使用されるバイナリ形式がなく、さまざまな形式があるためです。ストリーム バッファ (つまり、 から派生したクラスstd::streambuf
) を使用して、外部宛先からバイトを読み取ったり、外部宛先にバイトを書き込んだりできますが、バイナリ形式の入出力関数の適切なセットを作成する必要があります。
これに対するネイティブ サポートはありません。同様のことを実現したい場合は、シリアル化を使用してください。