コース一覧
    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分

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

    章の道具を1本にまとめる

    この章では、動的な表、コマンドライン引数、バイナリ保存、errno を1つずつ扱ってきました。今回はそれをまとめて、成績管理CLI を「起動するときに保存先を決めて、終わってもデータが残る」形にします。

    作るものの流れは次のとおりです。

    1. argv[1] を保存先として受け取る。無ければ案内して終わる
    2. 標準入力から人数と学生を読み、Student の動的配列に入れる
    3. 保存先へ fwrite でまとめて書き出し、配列を解放する
    4. 同じファイルを開き直し、入っている件数を数えて読み戻す
    5. 一覧と平均を表示して、確保したものを解放する

    保存先をプログラムの中に固定で書かないのがこの回の要点です。名前を外から渡せるようになると、クラスごとに別のファイルへ保存するといった使い分けが、プログラムを直さずにできます。

    件数をファイル自身から求める

    書いた側は件数を知っていますが、読む側は本来知りません。次に起動したとき「何件入っているか」を知る方法が要ります。1件の大きさが決まっているバイナリなら、ファイル全体の大きさを1件の大きさで割れば件数が出ます。

    c

    fseek(in, 0, SEEK_END);
    long bytes = ftell(in);
    fseek(in, 0, SEEK_SET);
    int count = (int)(bytes / (long)sizeof(Student));

    fseek は読み書きの位置を動かす関数で、SEEK_END を指定すると末尾へ飛びます。そこで ftell を呼ぶと先頭からのバイト数、つまりファイル全体の大きさが分かります。数え終わったら SEEK_SET で先頭へ戻してから読み始めます。戻し忘れると末尾から読もうとして 0 件になり、しかもエラーにはならないので気付きにくい失敗です。

    この割り算が成り立つのは、全部の件が同じ大きさで並んでいるからです。テキスト形式では1行の長さがまちまちなので同じ手は使えず、最後まで読んで数えるしかありません。バイナリの「決まった大きさで並ぶ」性質が効いている場面です。

    解放するタイミングを分けて考える

    書き出しに使った配列は fwrite が終われば役目を終えるので、そこで解放してかまいません。読み戻すための配列は、件数が分かってから改めて確保します。1つの変数を使い回さず、書く用と読む用を分けておくと、どちらがいつまで生きているのかがコードを読むだけで分かります。

    途中で失敗して return するときも、そこまでに確保したものは解放してから帰ります。すぐ終わるプログラムなら OS が片付けてくれますが、この形をそのまま長く動くプログラムへ持ち込むと、そこがリークになります。

    では、第6章の総まとめを書いてみましょう。

    要件

    1. 引数が無いときは 保存先のファイル名を引数で指定してください の1行だけを出して終わる
    2. あるときは 保存先はseiseki.binです の形で argv[1] を出す
    3. 標準入力から人数と 名前 点数 を読み、Student の動的配列に入れる
    4. fwrite で書き出し 3件保存しました の形で出し、書き出し用の領域を解放する
    5. 開き直して fseek と ftell で件数を求め、3件読み戻しました の形で出す
    6. 佐藤 80点 の形で一覧を出し、最後に 平均は79.0点です の形で小数第1位まで出す

    ヒント

    ftell で末尾の位置を取ったら、読み始める前に fseek で先頭へ戻します

    件数はファイルの大きさを sizeof(Student) で割って求めます。この値そのものは表示しません

    平均は (double) を付けてから割り、%.1f で出します

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

    関連レッスン

    • 第6章クイズ

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

    • リスト版を完成させる

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

    • エラーの調べ方

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

    • バイナリ保存

      構造体をそのままの形で保存して読み戻せるようになります。

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

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

    • コマンドラインキーボード入力で操作する画面
    • 引数位置引数=順番で渡す。
    • 配列サイズ固定の同型データの集まり
    • クラスデータと振る舞いを束ねる単位
    • 関数処理に名前を付けて再利用できる単位
    • 変数データに名前をつけて参照する仕組み
    main.c
    エディタを読み込んでいます

    メモ

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

    ⌘S で保存