fprintf関数には存在しないfwrite関数の第3引数について考察してみます fwrite(&hairetu[0],sizeof(int),1,fp);の1の部分ですね。

アレサ「


それではfwrite関数の第3引数について考察してみます 


《まずは次のプログラムを実行してみましょう》



#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),1,fp);

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

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


fclose(fp);

return 0;

}


コンパイル結果


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




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は


第3引数が1であることにより


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


さらに次の命令文


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


により

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


第3引数が1であることにより


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



次に


先のプログラムの

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

int hairetu[]={10,20,30};


に変更


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),0,fp);//ここです

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

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


に変更して


プログラムを実行してみます。


ソーラー「アレサ~絶好調だね~💖」


アレサ「はいっ」


#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[]={10,20,30};


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を開いて


中身を確認することができません。


そこで


バイナリファイルに何が書き込まれているかを


fread関数を使って配列によみこみ


配列に格納された、そのデータをprintf出力表示してみます。


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



#pragma warning(disable: 4996)

#include <stdio.h>

int main (void){


FILE *fp;

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

if(fp==NULL){

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

return -1;}

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

int hairetu[3];

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

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

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


printf("%d\n",hairetu[0]);

printf("%d\n",hairetu[1]);

printf("%d\n",hairetu[2]);


fclose(fp);

return 0;

}


コンパイル結果


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

20

30

1703808


ソーラー「ねえ、ねえ


なんで

1703808が表示されてるのかな


なんかまた配列が初期化されていないときに


格納されている数値が表示されてるみたいだけど・・・」


アレサ「はいっ



int hairetu[]={10,20,30};


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

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

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


int hairetu[]={10,20,30};

により

hairetu[0]

hairetu[1]

hairetu[2]

10

20

30

格納されます。


そして


hairetu[0]

hairetu[1]

hairetu[2]

に格納された数値

10

20

30

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]に格納された数値10は


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


次に

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


の書き込み回数を表す第3引数の数値が1になっていることにより


hairetu[1]に格納された数値20は


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


次に

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


の書き込み回数を表す第3引数の数値が1になっていることにより


hairetu[2]に格納された数値30は


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


ながくなりましたが大丈夫ですか(´▽`)


ですので、このとき


バイナリファイルに書き込まれている数値は


20

30

となります。

このとき

以前書き込みされた

数値

1

2

3


数値

20

30


TEN-GOGO-C-language.binに保存するときに


新規書き込み機能を持つオープンモード"wb"でファイルを


開いたので


TEN-GOGO-C-language.binファイル内から消去されています。


そして


バイナリファイルに書き込まれた

数値

20

30


次のプログラム


#pragma warning(disable: 4996)

#include <stdio.h>

int main (void){


FILE *fp;

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

if(fp==NULL){

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

return -1;}

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

int hairetu[3];

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

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

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


printf("%d\n",hairetu[0]);

printf("%d\n",hairetu[1]);

printf("%d\n",hairetu[2]);


fclose(fp);

return 0;

}



をもちいて


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


表示することになるわけですが



コンパイル結果は


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

20

30

1703808


が表示されます。


これは


バイナリファイルに

20

30

しか格納されていないため

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

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

により


20

30

が読み込まれると

3つ目の命令文

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

により

読み込まれる数値はもうないので


読み込まれる数値がないと


fread関数は機能しないので


hairetu[2]には何も数値が格納されず


hairetu[2]は初期化されないことになります


よってhairetu[2]が初期化されないときに


格納されている数値


1703808が


printf("%d\n",hairetu[2]);


によりコマンドプロンプト画面に表示されるというわけです。


ですので


コンパイル結果は


20

30

1703808


となるのですね。」













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

作者を応援しよう!

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

応援したユーザー

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