データをコンピュータが直接扱えるバイナリデータに変換しファイルに保存してみよう そのファイルはバイナリファイルと呼ばれます


今までは


自分で打ち込んだ文章や数値データ等を、


ハードデイスク内のファイルに保存してきました


実はそれらのデータはテキストファイルで開くことができるよう


つまり ファイルを開いたとき文字や数値として認識できるよう


テキストファイルのフォーマット(データ保存形式)で保存されています。


そのようなファイルはテキストファイルと呼ばれます


テキストファイルであることがわかるように


その際


ファイル名の末尾に.txtをつけて


TEN-GOGO-C-language.txt



保存してきました。


そして


データをハードデイスク内のファイルに保存するための


ファイルポインタ変数宣言とfopen関数の設定は


FILE *fp;

fp=fopen("TEN-GOGO-C-language.txt","w");


でした


もちろん


テキストファイル形式でファイルが開かれると


文字や数値と認識されることができるといっても


データがハードディスクに格納されているときは


0と1で表されたデータとして保存されています。


自分で打ち込んだ文章や数値データ等を



テキストファイルのフォーマット(データ保存形式)でなく


バイナリファイルのフォーマット(データ保存形式)



ハードデイスク内のファイルに保存することができます


バイナリファイルのフォーマット(データ保存形式)で


ハードディスクにデータが保存されるときも


0と1で表されたデータとして保存されています。



バイナリファイルのフォーマット(データ保存形式)で保存されたデータは


バイナリデータと呼ばれます


バイナリデータが保存されているファイルは


バイナリファイルと呼ばれます


バイナリファイルであることがわかりやすいように


ファイル名は


末尾に


TEN-GOGO-C-language.binのように


.binをつけます


データがテキストファイルのフォーマット(データ保存形式)


でなく


バイナリファイルのフォーマット(データ保存形式)


で保存されると


様々な利点があります。



それをこれから確認していきましょう。



バイナリファイルとしてデータを保存する際は


ファイルポインタ変数宣言とfopen関数の設定は


FILE *fp;

fp=fopen("TEN-GOGO-C-language.txt","w");


でなく


FILE *fp;

fp=fopen("TEN-GOGO-C-language.bin","wb");


となります。


2つの

ファイルポインタ変数宣言とfopen関数の設定を

よく見比べてみると


fp=fopen("TEN-GOGO-C-language.txt","w");

fp=fopen("TEN-GOGO-C-language.bin","wb");


では

ファイル名が.txtから.binに


オープンモードが"w"から"wb"に変化しています。


ここでの


オープンモード"wb"は


オープンモード"w"に相当し


ハードディスク内に


TEN-GOGO-C-language.binファイルを作製し


新規書き込みできるモードで


TEN-GOGO-C-language.binファイルを開きます。


同様に


オープンモード "a","r" に相当する

オープンモード "ab","rb"もあり


それぞれ


追加書き込みモード

読み込み専用モード

となっています。


ここでファイル名を.binとしなくても

.yahoo や.comとしても


バイナリファイルを作成することはできますが


あとでそのファイルが


テキストファイルかバイナリファイルか


どのようなタイプのファイルだったか


判断できなくなるので


ファイル名を.binとしています。



バイナリファイルである 

TEN-GOGO-C-language.binファイルを


新規作製、オープンしてからクローズするまでの


プログラムは次のようになります。



#pragma warning(disable: 4996)

#include <stdio.h>

int main (void){


FILE *fp;

fp=fopen("TEN-GOGO-C-language.bin","wb");

if(fp==NULL){

printf("ファイルオープンに失敗しましたよ~ん\n");

return -1;}

else printf("Hello!ファイルオープンに成功しましたよ~ん\n");


fclose(fp);

return 0;

}


コンパイル結果

Hello!ファイルオープンに成功しましたよ~ん



ファイルポインタ変数fp宣言、fopen関数の設定

FILE *fp;

fp=fopen("TEN-GOGO-C-language.bin","wb");


が行われると


ハードディスク内にバイナリファイルである


TEN-GOGO-C-language.binファイルがない場合は


新たに

TEN-GOGO-C-language.binファイルが作成され


オープンモード"wb"で開かれます。


ハードディスク内にバイナリファイルである


TEN-GOGO-C-language.binファイルがある場合は


そのハードディスク内のTEN-GOGO-C-language.binファイルが


オープンモード"wb"で開かれます。


そのとき

TEN-GOGO-C-language.binファイルに保存されていたデータは


消去されてしまいます。


このバイナリファイルを開くプログラムでも


ファイルオープンに成功していると


fopen("TEN-GOGO-C-language.bin","wb")は


NULL以外の戻り値を


ファイルオープンに失敗していると


fopen("TEN-GOGO-C-language.bin","wb")は


NULLという戻り値を持つよう


設定されています


ファイルオープンに失敗していると


fp=fopen("TEN-GOGO-C-language.bin","wb");


より



ファイルポインタ変数fpは


fp=NULLという値を持つようになるので


バイナリファイルが正常にオープンしているかどうかを確認するために


if(fp==NULL){

printf("ファイルオープンに失敗しましたよ~ん\n");

return -1;}

else printf("Hello!ファイルオープンに成功しましたよ~ん\n");


を記述しています


このように記述することで


ファイルオープンに失敗したとき



ファイルオープンに失敗しましたよ~ん



ファイルオープンに成功したとき



ファイルオープンに成功しましたよ~ん


がコマンドプロンプト画面に表示されるので


正しくファイルが開けているかをどうかを確認することができます。


それでは例として


数値

1

2

3


バイナリファイルTEN-GOGO-C-language.binに保存してみます


そのプログラムは


次のように記述します。



#pragma warning(disable: 4996)

#include <stdio.h>


int main (void){


FILE *fp;

fp=fopen("TEN-GOGO-C-language.bin","wb");

if(fp==NULL){

printf("ファイルオープンに失敗しましたよ~ん\n");

return -1;}

else printf("Hello!ファイルオープンに成功しましたよ~ん\n");


int hairetu[]={1,2,3};

/*ここに注目


TEN-GOGO-C-language.binファイルにデータを保存したい場合


まず

TEN-GOGO-C-language.binファイルに

書き込みしたい数値

1

2

3

fwrite関数をつかって

用意した配列の

配列変数

hairetu[0]

hairetu[1]

hairetu[2]

に格納します*/



fwrite(&hairetu[0],sizeof(int),1,fp);

fwrite(&hairetu[1],sizeof(int),1,fp);

fwrite(&hairetu[2],sizeof(int),1,fp);


/*このように


fprintf関数のときとは数値をファイルに保存するときの

表記法が大分ことなります

保存したい数値は

まず

配列変数

hairetu[0]

hairetu[1]

hairetu[2]


に格納してから

ハードディスク内のTEN-GOGO-C-language.binファイルに

fwrite関数を用いて

保存されていきます。

*/


fclose(fp);

return 0;

}


コンパイル結果

Hello!ファイルオープンに成功しましたよ~ん



さきのエピソードで見てきたように


テキストファイルのTEN-GOGO-C-language.txtファイルに


数値データ

1

2

3

書き込み保存するときは


fprintf関数をもちいて


次のプログラムのように


#pragma warning(disable: 4996)

#include <stdio.h>


int main (void){


FILE *fp;

fp=fopen("TEN-GOGO-C-language.txt","w");

if(fp==NULL){

printf("ファイルオープンに失敗しましたよ~ん\n");

return -1;}

else printf("Hello!ファイルオープンに成功しましたよ~ん\n");


fprintf(fp,"%d\n",1);

fprintf(fp,"%d\n",2);

fprintf(fp,"%d\n",3);

fclose(fp);

return 0;

}

記述されていました。


このとき

fprintf関数を用いて

数値

1

2

3


ハードディスク内のファイルに書き込む形式は

fprintf(fp,"%d\n",1);

fprintf(fp,"%d\n",2);

fprintf(fp,"%d\n",3);


となっていました




TEN-GOGO-C-language.binファイルに


数値データ

1

2

3

バイナリデータ


として書き込み保存する際には


fwrite関数をもちいます。


fwrite関数をつかって数値をハードディスク内のファイルに書き込む形式は


fwrite(&hairetu[0],sizeof(int),1,fp);

fwrite(&hairetu[1],sizeof(int),1,fp);

fwrite(&hairetu[2],sizeof(int),1,fp);


となります


このとき命令文

fwrite(&hairetu[0],sizeof(int),1,fp);

が行われると

ハードデイスク内のbinファイルの1行目に


アドレス&hairetu[0]のメモリに格納されているデータ


1


かきこまれます。


そして次の命令文

fwrite(&hairetu[1],sizeof(int),1,fp);

が行われると

ハードデイスク内のbinファイルの2行目に


アドレス&hairetu[1]のメモリに格納されているデータ

2


がかきこまれます。


このように

fwrite文が1つ実行されるたびに


fwrite文の第1引数のアドレスのメモリに格納されているデータは

1行ごとに

行を変えながら

保存されていきます。


そして


さらに

fwrite(&hairetu[2],sizeof(int),1,fp);

が実行されると


さらに

次の行にアドレス&hairetu[2]のメモリに格納されているデータ


3


かきこまれていきます。


このときの


fwrite文

fwrite(&hairetu[1],sizeof(int),1,fp);

fwrite(&hairetu[0],sizeof(int),1,fp);

fwrite(&hairetu[2],sizeof(int),1,fp);


をみてもわかるように


データをbinファイルの次の行に保存するのに


改行するためのエスケープシーケンス\


を記述する必要はないのです。


テキストファイルにデータを保存する

fprintf関数の表記法


fprintf(fp,"%d\n",1);

fprintf(fp,"%d\n",2);

fprintf(fp,"%d\n",3);


バイナリファイルにデータを保存する

fwrite関数の表記法


fwrite(&hairetu[0],sizeof(int),1,fp);

fwrite(&hairetu[1],sizeof(int),1,fp);

fwrite(&hairetu[2],sizeof(int),1,fp);


では表記法が随分異なりますね


この

数値

1

2

3

バイナリデータ


として


ファイルに書き込み保存するプログラムでは


         🍋 あらかじめ 🍋


配列宣言

int hairetu[]={1,2,3};

を行い


保存したい数値

1

2

3

int hairetu[]={1,2,3};

より生成される

配列変数           


               hairetu[0]

               hairetu[1]

               hairetu[2]


               hairetu[0]=1

               hairetu[1]=2

               hairetu[2]=3


と格納します



hairetu[0]に数値データが


格納されています。


数値データ


1


をそのまま


バイナリファイルに書き込み保存する場合に


用いられるのが


fwrite関数になります。


fwrite関数の第1引数には


fwrite(&hairetu[0],sizeof(int),1,fp);

のように


数値1を格納しているhairetu[0]の


   🍅アドレス&hairetu[0]🍅


をかきこみます



2番目の引数には


保存したい数値データが整数の場合 sizeof(int)

保存したい数値データが実数の場合 sizeof(float)

あるいは

sizeof(double)

をかきこみます。


int型は4バイトのデータ格納容量

float型も4バイトのデータ格納容量

double型は8バイトのデータ格納容量


をもつので


変数の型の格納容量をあらわすsizeof演算子により


sizeof(int)

sizeof(float)

sizeof(double)

それぞれ

sizeof(int)=4

sizeof(float)=4

sizeof(double)=8


に等しくなります


ですので


fwrite(&hairetu[0],sizeof(int),1,fp);

fwrite(&hairetu[0],sizeof(double),1,fp);


の代わりに


fwrite(&hairetu[0],4,1,fp);

fwrite(&hairetu[0],8,1,fp);

と記述することもできます


この第2引数に書き込まれた数値を単位として


バイナリファイルにバイナリデータは書き込まれていきます


つまり

fwrite(&hairetu[0],4,1,fp);

なら

4バイトのスペースを持つお部屋に


アドレス&hairetu[0]のメモリに格納されている数値データ1



格納されます


つまり


バイナリファイルの1行が


4バイトのデータ格納スペースを持つことになります。


fwrite(&hairetu[0],8,1,fp);

なら

8バイトのスペースを持つお部屋にアドレス&hairetu[0]のメモリに

格納されている数値1


は格納されます


つまり

バイナリファイルの1行が8バイトのデータ格納スペースを持つことになります。



そして


fwrite関数の第3引数は


保存したいデータを書き込む回数をあらわしています。


fwrite(&hairetu[0],sizeof(int),1,fp);

と記述されたとき


3番目の引数1は


バイナリファイルに

&hairetu[0]のアドレスのメモリに格納された数値1



1回書き込むことを表しています。


fwrite(&hairetu[0],sizeof(int),0,fp);

fwrite(&hairetu[1],sizeof(int),1,fp);

fwrite(&hairetu[2],sizeof(int),1,fp);


なら

fwrite(&hairetu[0],sizeof(int),0,fp);

の第3引数は0なので


&hairetu[0]のアドレスのメモリに格納された数値1

1回もバイナリファイルに書きこまれません。


そして次の命令文


fwrite(&hairetu[1],sizeof(int),1,fp);


により

&hairetu[1]のアドレスのメモリに格納された数値2



1回バイナリファイルに書きこまれ


さらに次の命令文


fwrite(&hairetu[2],sizeof(int),1,fp);


により

&hairetu[2]のアドレスのメモリに格納された数値3

1回バイナリファイルに書きこまれます。



実際にプログラムを構成して確認してみます。


#pragma warning(disable: 4996)

#include <stdio.h>


int main (void){


FILE *fp;

fp=fopen("TEN-GOGO-C-language.bin","wb");

if(fp==NULL){

printf("ファイルオープンに失敗しましたよ~ん\n");

return -1;}

else printf("Hello!ファイルオープンに成功しましたよ~ん\n");


int hairetu[]={1,2,3};


fwrite(&hairetu[0],sizeof(int),0,fp);

fwrite(&hairetu[1],sizeof(int),1,fp);

fwrite(&hairetu[2],sizeof(int),1,fp);


fclose(fp);

return 0;

}


コンパイル結果

Hello!ファイルオープンに成功しましたよ~ん


PC内検索を行うと

バイナリファイル

TEN-GOGO-C-language.bin

が作成されているのがわかります。


しかし


バイナリファイルである


TEN-GOGO-C-language.binファイルは


テキストファイルを開くソフトを使って


開いて中身を閲覧することができない仕様になっていますので


TEN-GOGO-C-language.binファイルに


どんなデータが保存されているかを調べるためには


fread関数を使って


TEN-GOGO-C-language.binファイルからデータを


読み取る必要があります。


fread関数については次のエピソードでお話しますので


続きは後ほどとなります。



fwrite関数の4番目の引数となっている


ファイルポインタ変数fpは


fwrite(&hairetu[0],sizeof(int),1,fp);


が実行されると


int hairetu[]={1,2,3};


により


メモリに格納された数値


1


ファイル構造体をとおして


別の

メモリに格納するはたらきをしています


そのメモリのアドレスを


ファイルポインタ変数fpは格納することになります。


そのメモリに格納された


数値データ

1


ハードデイスク内のバイナリファイルに


そのまま保存されるという仕組みとなっています



そうして

fwrite(&hairetu[0],sizeof(int),1,fp);

fwrite(&hairetu[1],sizeof(int),1,fp);

fwrite(&hairetu[2],sizeof(int),1,fp);


が全て実行されると


ハードデイスク内のバイナリファイルに


数値データ

1

2

3


は保存されます。


このように


fwrite関数により保存したいデータが配列から


ファイルポインタ変数fpをつかって


別のメモリに移し替えられた後


ハードディスク内のTEN-GOGO-C-language.binファイルに


その保存したいデータは送り込まれ保存されます



新規書き込みモード"w"のように


新規書き込みモード"wb"でファイルが開かれる場合


以前バイナリファイルに保存されていたデータはすべて消えてしまいます



新規書き込みモード"r"のように


読み込みモード"rb"でファイルが開かれている場合


バイナリファイルからデータの読み込みしかできない状態になっています


バイナリファイルからデータの読み込みを行うときは


ファイルポインタ変数fpの格納しているアドレスのメモリに


バイナリファイルのデータは格納されることになります。


そして


次のエピソードで出てくる


fread関数は


ハードディスクのバイナリファイルのバイナリデータを


ファイルポインタ変数fpの格納しているアドレスのメモリに格納して


さらに


メモリに格納されたバイナリファイルのバイナリデータを


用意した配列の配列変数に移し替えます。


その後


配列変数に格納されたデータをprintf関数を使って


printf出力表示することにより


コマンドプロンプト画面に


バイナリファイルに保存されていたデータが表示されることになります。



🌞     🌞     🌞     🌞      🌞




ソーラー「はっ?僕はどこで今何してるんですか?」


アレサ 「もう、寝ながら起きながらボケようとするんですから」


ソーラー「まあ、それはいつもそうだけど・・・」


アレサ 



#pragma warning(disable: 4996)

#include <stdio.h>


int main (void){


FILE *fp;

fp=fopen("TEN-GOGO-C-language.bin","wb");

if(fp==NULL){

printf("ファイルオープンに失敗しましたよ~ん\n");

return -1;}

else printf("Hello!ファイルオープンに成功しましたよ~ん\n");


int hairetu[]={1,2,3};


fwrite(&hairetu[0],sizeof(int),0,fp);

fwrite(&hairetu[1],sizeof(int),1,fp);

fwrite(&hairetu[2],sizeof(int),1,fp);


fclose(fp);

return 0;

}


コンパイル結果

Hello!ファイルオープンに成功しましたよ~ん


このバイナリファイルにバイナリデータとしてデータを保存する


プログラムの実行後


TEN-GOGO-C-language.binを


PC内検索にかけて検索すると


バイナリファイルTEN-GOGO-C-language.binが


作成されているのをみつけることができます。


ですが


バイナリファイルをひらいて中身を確認することは


できません。


開こうとしても.bin形式のファイルを開くことはできません


とパソコン画面に表示されます


おしいです・・・」


ソーラー「ほんとだ バイナリファイルを開くには


どうやら専用ソフトでもいるのかな?」


  • Xで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る