コース一覧
    C言語中級 連結リスト・応用
    バイナリ保存

    C言語中級 連結リスト・応用

    C言語の連結リストと応用的なデータ操作を学び、実装でデータを扱うコースです。

    1
    連結リスト
    01. 配列の限界15分
    02. ノードを定義する15分
    03. 先頭に追加する15分
    04. リストを歩く15分
    05. 任意位置の挿入と削除15分
    06. リストを全解放する15分
    07. つくる リスト版成績管理15分
    08. 第5章クイズ10分
    2
    応用
    01. 動的な二次元配列15分
    02. コマンドライン引数15分
    03. バイナリ保存15分
    04. エラーの調べ方15分
    05. つくる 引数とバイナリ保存15分
    06. 第6章クイズ10分
    3
    総合制作
    01. リスト版を完成させる20分
    02. メモリバグ演習20分
    03. 自由拡張20分
    04. 完成と次のステップ10分

    バイナリ保存

    構造体をそのままの形で保存する

    入門のファイル入出力では、fprintf で数値を文字に直して書き、fscanf で文字を数値に戻して読みました。人が中身を読めるのは大きな利点ですが、書くたびに変換が入り、構造体の項目が増えるほど書式の指定が長くなります。

    もう1つのやり方が、メモリにある並びをそのまま書き出す バイナリ保存 です。

    c

    FILE *fp = fopen("students.bin", "wb");
    fwrite(list, sizeof(Student), n, fp);
    fclose(fp);

    fwrite に渡すのは、先頭のアドレス、1個あたりの大きさ、個数、ファイルの4つです。戻り値は 書けた個数 で、頼んだ個数と違えば途中で失敗しています。読むときは同じ形の fread を使い、こちらの戻り値は 読めた個数 になります。

    c

    FILE *fp = fopen("students.bin", "rb");
    int got = (int)fread(loaded, sizeof(Student), n, fp);

    "wb" と "rb" の b はバイナリの意味です。Linux や macOS では付けても付けなくても同じ動きですが、Windows では改行にあたるバイトが勝手に書き換えられてデータが壊れます。付ける習慣にしておくのが安全です。

    何がうれしくて、何が危ないか

    変換が無いぶん速く、名前に空白が入っていても fscanf のように途中で切れません。1件の大きさが決まっているので、5件目だけを読みたいときに先頭から順に読み直さず、いきなりその位置へ飛べるのも利点です。

    一方で、書き出したファイルは人には読めず、テキストエディタで直せません。さらに 別の環境で読めるとは限りません。int の大きさ、バイトを並べる向き、構造体に入る詰め物の量は処理系によって変わります。同じプログラムが作って同じプログラムが読む、という前提のときだけ使える形式だと考えてください。長く保存したいものや、他のプログラムに渡すものは、テキストや決まった形式のほうが安全です。

    ポインタを含む構造体は保存できない

    保存してはいけないものが1つあります。ポインタを持つ構造体 です。Node *next を書き出しても、ファイルに残るのはそのときの番地の数値だけで、次に起動したときには何も指していません。読み戻したあとにたどると、まったく無関係な場所へ飛びます。

    第5章の連結リストをそのまま fwrite できないのはこのためです。リストを保存するときは、中身だけを1件ずつ書き出し、読むときに改めてつなぎ直します。

    このレッスンでは、書いてすぐ読み戻すところまでを1本のプログラムで確かめます。

    要件

    1. fwrite で Student をそのまま書き出し、3件書き込みました の形で書けた件数を出す
    2. 同じファイルを開き直し、fread で読み戻して 3件読み戻しました の形で読めた件数を出す
    3. 読み戻した内容を 佐藤 80点 の形で1件ずつ出す
    4. 開くモードは書き込みが wb、読み込みが rb にする

    ヒント

    fwrite と fread の戻り値は個数です。int に入れて %d で出すと桁の指定に悩みません

    読むときは書いた件数を知らないつもりで、MAX_STUDENTS 件まで頼んで、戻り値で実際の件数を受け取ります

    生田 陸人
    監修生田 陸人
    ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
    編集 ゆめさく編集部·公開 2026/08/07

    関連レッスン

    • エラーの調べ方

      失敗の理由を具体的に表示できるようになります。

    • つくる 引数とバイナリ保存

      起動と保存を実用的な形にできるようになります。

    • 第6章クイズ

      二次元確保、引数、バイナリ保存の理解を確認します。

    • リスト版を完成させる

      全機能をリスト前提で1本にまとめられるようになります。

    このレッスンに出てくる用語

    意味があいまいなまま進んだ語は、ここから読み直せます。

    • 入出力input()はユーザーからの入力を文字列として受け取る関数。
    • メモリプログラムとデータを一時保持する高速領域
    • 戻り値呼び出し元への返答を表す点線矢印
    • 処理計算や代入を表す長方形
    • 連結リスト各要素が次の要素へのポインタを持つ構造。
    • リスト順序付きで複数の値を扱うデータ構造
    main.c
    エディタを読み込んでいます

    メモ

    バイナリ保存

    ⌘S で保存