
C言語基礎|ファイルのオープン
「ファイルは“開いてから”がスタート! fopen で入出力の扉を開けよう。」
ノートを使うときって、まず表紙を開きますよね。開かないと読めないし、書けない。
C言語のファイル処理もまったく同じで、**最初にファイルを開く(オープンする)**ところから始まります。
この「開く」を担当するのが fopen 関数です。
fopen は、ファイルとストリームを結びつけて、以後の読み書きに使う通り道(ストリーム)を準備してくれます。
そしてその通り道を操作するための“取っ手”として、FILE(FILE型へのポインタ)を返します。

まず押さえる要点(超重要)
- ファイルを使うときは、まず fopen でオープンする
- fopen は成功すると FILE* を返す
- 失敗すると NULL を返す(つまり「どこも指していないポインタ」)
図でつかむ:fopen がやっていること
図:ファイル名とモードを渡して、ストリーム(fp)を受け取る

図の説明
- 第1引数の「ファイル名」で、どのファイルを扱うか決めます。
- 第2引数の「モード」で、読みたいのか/書きたいのか/追記したいのか…を決めます。
- fopen が内部でストリームを用意して、制御に必要な情報を FILE 型として管理し、その場所を指す FILE* を返してくれます。
- 以後はこの fp を使って、読み書きの関数に「このファイルに対してやってね」と指示します。
サンプルプログラム
メモ用ファイル memo.txt に1行だけ追記するシンプルなプログラム例です。
「追記(a)」モードを使うと、既存の内容を壊さず末尾に追加できます。
プロジェクト名:chap13-2-1 ソースファイル名:chap13-2-1.c
Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。
Windows の Visual Studio が実行環境の場合、以下のパスに「memo.txt」が作成されます。
C:\Users\<ユーザー名>\source\repos\chap13-2-1\chap13-2-1
#include <windows.h>
#include <stdio.h>
int main(void)
{
SetConsoleOutputCP(65001); // 出力をUTF-8に設定
FILE *fp;
fp = fopen("memo.txt", "a");
if (fp == NULL) {
fprintf(stderr, "ファイルを開けませんでした。保存先を確認してください。\n");
return 1;
}
fprintf(fp, "今日はファイル入門を進めた!\n");
fclose(fp);
printf("メモを書き込みました。\n");
return 0;
}このプログラムで起きている流れ(文章で説明)
- fopen("memo.txt", "a") で memo.txt を「追記モード」で開きます。
- fp が NULL ならオープン失敗なので、stderr にエラーメッセージを出して終了します。
- 成功したら fprintf(fp, ...) で fp に結び付いたストリームへ文字列を流し込み、結果としてファイル末尾に追記されます
- 最後に fclose(fp) でファイルを閉じます(開いたら閉じる、が基本です)
- 仕上げに stdout へ完了メッセージを出します。
fopen の書式と引数をやさしく分解
書式
| 項目 | 内容 |
|---|---|
| ヘッダ | #include <stdio.h> |
| 形式 | FILE *fopen(const char *filename, const char *mode); |
| 役割 | filename のファイルを mode の指定で開き、ストリームに結び付ける |
| 返り値 | 成功:FILE* / 失敗:NULL |
表の説明
- FILE* は「このストリーム(このファイル操作の窓口)を使ってね」というハンドル(取っ手)です。
- filename と mode は文字列(char の並び)で渡します。
- 失敗時は NULL なので、必ず if (fp == NULL) のチェックを入れるのが安全です。
モードってなに?(読み方を表で整理)
モードは「どう開くか」の指定です。まずは頻出のものから覚えるとラクです。
代表的なモードの意味(テキスト / バイナリ)
| モード | 種類 | 主な用途 | ポイント |
|---|---|---|---|
| r | テキスト | 読み取り | ファイルが存在しないと失敗しやすい |
| w | テキスト | 書き込み(新規作成/上書き) | 既存内容は消えて0からになる |
| a | テキスト | 追記 | 書き込みは常に末尾に追加される |
| rb | バイナリ | 読み取り | バイナリとして読む |
| wb | バイナリ | 書き込み(新規作成/上書き) | バイナリとして書く |
| ab | バイナリ | 追記 | バイナリ末尾へ追加 |
表の説明(ここがイメージのコツ)
- r は「読むだけ」。存在しないと読めないので失敗しやすいです。
- w は「書くために用意する」。既にあれば中身を消して作り直す、と思うと安全です。
- a は「末尾に足す」。ログやメモにぴったりです。
- b が付くと「バイナリ扱い」。本節はテキスト中心なので、まずは r / w / a を押さえればOKです。
更新モード(+)の考え方:読み書き両方やりたいとき
- を付けると「更新(読取りと書込み)」になります。
表:+ が付くモードの概要
| モード | できること | 注意点(重要) |
|---|---|---|
| r+ | 既存ファイルを読み書き | 存在しないと基本失敗 |
| w+ | 読み書き(新規/上書き) | 中身は0からになる |
| a+ | 読み書き(追記ベース) | 書き込みは末尾に寄りやすい |
表の説明(なぜ注意が必要?)
更新モードでは「読み」と「書き」を交互にやりがちです。
このとき、処理系のルールとして 読み→書き や 書き→読み の切り替えの間に、ファイル位置を調整する関数(fseek / rewind など)を挟まないと、期待通り動かないことがあります。
最初は無理に混ぜず、読むだけ / 書くだけ / 追記だけで慣れていくのが安心です。
追加モード(a)の“末尾固定”を図で確認
追加モードは「いつ書いても末尾に付く」という性質が大事です。
図:a で開いたファイルは書き込み位置が末尾へ

図の説明
- a モードで開いた場合、途中に移動して書こうとしても、最終的に末尾に追加される動きになります。
- ログ追記に向いている一方で、「途中を上書きしたい」用途には向きません。
NULL が返るとはどういうこと?
fopen に失敗すると NULL が返ります。これは「有効なストリームを指していない」という意味です。
図:成功と失敗の違い

図の説明
- fp が NULL のまま fprintf(fp, ...) のように使うと危険です(未定義動作につながります)。
- なので「開けたかどうかの確認」は、ファイル処理の基本の基本です。
fopen まわりでよく出てくる“登場人物”まとめ
ファイルオープン周辺の用語と役割
| 用語 | 役割 | ひとことで |
|---|---|---|
| ファイル名 | 対象のファイルを指定 | どれを開く? |
| モード | 開き方を指定 | 読む?書く?追記? |
| ストリーム | データの流れ道 | 文字が流れる川 |
| FILE | ストリーム管理情報の型 | 状態を持つ管理票 |
| FILE* | FILE を指すポインタ | 操作用ハンドル |
| NULL | “無効”を表す | 失敗の合図 |
表の説明
- FILE は中身(実装)は処理系依存でも、役割は「管理情報」だと思ってOKです。
- 私たちは FILE* を通して、その管理情報+ストリームに指示を出していきます。
ひとことアドバイス(習慣にすると強い)
- fopen の直後は fp == NULL を必ずチェック
- 開いたら最後は fclose(開けっぱなしにしない)
- まずは r / w / a の3つを確実にしてから + に挑戦
