
C言語入門|int型データをバイナリとして読み書きする
前の記事では、char配列をバイナリデータとして読み書きする方法を学びました。
ここでは一歩進んで、int型の数値そのものをバイナリとしてファイルに保存し、再び読み取る方法を解説します。
数値データをバイナリで扱えるようになると、
- セーブデータ
- 設定ファイル
- 高速な数値データの保存・復元
といった実用的な処理が書けるようになります。
ポイントはとてもシンプルで、
文字列と違って、int型はサイズが決まっているため、そのサイズ分をそのまま読み書きする
という考え方です。

サンプルプログラム:int型をバイナリとして読み書きする
次のプログラムは、
- int型変数に格納された数値をバイナリファイルに書き込み
- 同じファイルから int型データを読み取り
- 画面に表示する
という流れになっています。
サンプルプログラム
プロジェクト名:14-11-1 ソースファイル名: sample14-11-1.c
Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE* fp;
int wbuf = 100; // 書き込みデータ
int rbuf; // 読み取り用データ
/* --- バイナリ書き込み --- */
if ((fp = fopen("try.dat", "wb")) == NULL) {
printf("ファイルを開けませんでした\n");
exit(1);
}
fwrite(&wbuf, sizeof(int), 1, fp); // int型を1個書き込む
fclose(fp);
/* --- バイナリ読み取り --- */
if ((fp = fopen("try.dat", "rb")) == NULL) {
printf("ファイルを開けませんでした\n");
exit(1);
}
int cn = fread(&rbuf, sizeof(int), 1, fp); // int型を1個読み取る
fclose(fp);
printf("%d個のデータを読み取りました:%d\n", cn, rbuf);
return 0;
}実行結果
1個のデータを読み取りました:100fwrite による int型データの書き込み
書き込み処理の中心は、次の1行です。
fwrite(&wbuf, sizeof(int), 1, fp);この呼び出しを分解して考えてみましょう。
| 引数 | 意味 |
|---|---|
| 第1引数 | 書き込むデータの先頭アドレス |
| 第2引数 | データ1個あたりのサイズ |
| 第3引数 | 書き込むデータの個数 |
| 第4引数 | ファイルポインタ |
ここでは、
- 書き込むデータは int型変数 wbuf
- int型のサイズは sizeof(int) バイト
- 個数は 1
となっているため、
wbuf が占めているメモリ領域を、そのままバイナリデータとして書き込む
という処理になります。
文字列とは違い、'\0' や改行といった概念は一切関係ありません。
fread による int型データの読み取り
読み取り処理も、考え方はまったく同じです。
int cn = fread(&rbuf, sizeof(int), 1, fp);この処理では、
- sizeof(int) バイト分のデータを
- 1個分
読み取り、その結果を rbuf のメモリ領域に直接格納します。
戻り値 cn には、実際に読み取れたデータの個数が入ります。
今回のように正常に読み取れた場合は 1 になります。
なぜ & を付けているのか
char配列のときとは違い、int型の読み書きでは 必ず & を付けてアドレスを渡している点に注目してください。
fwrite(&wbuf, sizeof(int), 1, fp);
fread(&rbuf, sizeof(int), 1, fp);これは、
- 配列名は自動的に先頭アドレスになる。
- 変数名は値そのものを表す。
という C言語のルールによるものです。
int型データをバイナリとして扱う場合は、
値ではなく、その値が置かれているメモリの場所を渡す
という考え方が重要になります。
char配列との違いを整理する
ここで、前節の char配列との違いを簡単にまとめておきましょう。
| データ型 | 第1引数に渡すもの | '\0' の扱い |
|---|---|---|
| char配列 | 配列名 | 自分で付ける必要あり |
| int型 | &変数名 | 不要 |
int型はサイズが固定されているため、
サイズ指定だけで完全に読み書きが完結するのが特徴です。
まとめ
- int型は サイズが決まったバイナリデータ
- fwrite と fread は サイズと個数で読み書きする。
- int型では必ずアドレスを渡す。
- '\0' などの文字列特有の処理は不要
この考え方が理解できれば、
次は 配列や構造体をまとめてバイナリ保存する ことも自然に理解できるようになります。
