バイナリ・ファイル入出力
ファイル入出力をバイナリで行うVisual C++2010コンソール・アプリケーション例を以下のように作成した。
#include "stdafx.h" // Visual
C++が自動的に用意するもの
#include <iostream> // C++標準入出力cinおよびcout用
#include <fstream> // ofstream用
#include <string> // string型用
using namespace std;
int _tmain(int argc,
_TCHAR* argv[])
{
string
flnm1;
cout << "File Name1
= ";
cin >> flnm1;
ofstream fout;
fout.open(flnm1);
int a = 123, b = 456, c =
789;
fout << a << "
" << b << " "
<< c;
fout.close();
cout << "File Name2
= ";
char flnm2[100];
cin >> flnm2;
FILE
*pfout;
pfout = fopen(flnm2, "w");
// fopen_s(&pfout, flnm2,
"w"); // fopenのsecurity強化版
fwrite(&a, 4, 1, pfout);
fwrite(&b, 4, 1, pfout);
fwrite(&c, 4, 1, pfout);
fclose(pfout);
ifstream fin;
fin.open(flnm1);
int a1, b1, c1;
fin
>> a1 >> b1 >> c1;
fin.close();
cout << "a1 = "
<< a1 << " b1 = " << b1
<< " c1 = " << c1
<< endl;
FILE
*pfin;
// pfin = fopen(flnm2,
"r");
fopen_s(&pfin, flnm2, "r"); // fopenのsecurity強化版
int a2, b2, c2;
fread(&a2, 4, 1, pfin);
fread(&b2, 4, 1, pfin);
fread(&c2, 4, 1, pfin);
fclose(pfin);
cout << "a2 = "
<< a2 << " b2 = " << b2
<< " c2 = " << c2
<< endl;
cout << "Enter any
character" << endl;
cin >> flnm1;
return 0;
}
上のプログラムではテキストファイル入出力も行い、バイナリファイル入出力との比較が出来るようにした。テキストファイル入出力は別のウェブサイト<テキストファイル入出力>で説明している。
C++のプログラムとして作成しているが、バイナリ・ファイル入出力はCの関数を用いている。
バイナリ・ファイル出力のため、まずFILE型のポインタ変数pfoutを
FILE *pfout;
pfout = fopen(flnm2, "w");
と用意している。flnm2はファイル名が設定されたchar*型であり、第2引数に”w”を指定して書き出しであることを示している。
Visual C++2010でコンパイルすると、より安全なfopen_s関数を用いるように警告が出される。fopen_sを用いる場合は
fopen_s(&pfout, flnm2, "w");
のようにする。第1引数にFILE型のポインタ変数pfoutのアドレス&pfout、第2引数にファイル名、第3引数には書き出しの場合”w”を設定する。
fopenあるいはfopen_sで用意されたポインタpfoutによるバイナリ出力をfwrite関数を用いて
fwrite(&a, 4, 1, pfout);
と行っている。fwrite関数の引数は
fwrite( 出力ブロックへのポインタ, データ1個分のバイト数, データの出力個数, 出力先ファイルポインタ );
の形式で用意する。第1引数は出力ブロックへのポインタであり、上の例の場合は整数型変数aのアドレス&aである。整数型intは4バイトの大きさであるので2番目の引数には4が設定されている。この整数型を1個書き出すので3番目の値は1である。4番目の引数は上で設定した出力先pfoutである。
バイナリファイルからの読み込みは
FILE *pfin;
// pfin = fopen(flnm2, "r");
fopen_s(&pfin, flnm2, "r"); // fopenのsecurity強化版
int a2, b2, c2;
fread(&a2, 4, 1, pfin);
と行っている。読み込みであるのでfopen_s関数の3番目の引数を”r”としていること、読み込みの関数としてfreadを用いていることを除いて書き出しの場合と同様である。
上の関数の実行例を図1に示す。
図1
図1の画面の状態で何か文字キーを押してからEnterキーを押すとプログラムの実行終了となる。
プログラムの実行終了後、2つのファイルf1とf2をエディタで開くと図2および図3のようになっている。
図2
図2は、テキストファイル出力されたファイルf1をテキストエディタで開いたものであるのでファイル内容がテキストとして表示される。しかし、f2はバイナリファイル出力されたものであるので、出力した整数値がそのまま数値を表すテキストとしては書き出されていない。表されている整数値のメモリー上での内部表現の出力されたものがテキストエディタで表示されている。例えば、である。
図3
なお、Visual C++/CLRによるバイナリ・ファイル入出力は<岡本安晴「大学生のための心理学VC++プログラミング入門」勁草書房、pp.295-298>で説明している。
また、バイナリファイル出力とテキストファイル出力のサイズ比較を標準C++で行った場合をウェブサイト<バイナリ・ファイル出力とテキスト・ファイル出力の比較>で、Visual C++/CLRで行った場合をウェブサイト<バイナリ・ファイル出力とテキスト・ファイル出力の比較>で説明している。