
C言語基礎|ファイルのクローズ
「開いたら、ちゃんと閉じる。これが“安全なファイル処理”の第一歩!」
ノートって、読み書きが終わったら閉じますよね。机の上に開きっぱなしだと邪魔だし、どこまで読んだかも曖昧になりがちです。
C言語のファイルも同じで、使い終わったら**ファイルとストリームの結び付きを切り離して、後片付け(クローズ)**をします。
この「後片付け」を担当するのが fclose 関数です。
クローズするときは、ただ“閉じる”だけじゃなくて、まだファイルに書き込まれていないデータをまとめて書き出す(フラッシュ)など、大事な処理も一緒に行われます。
なので、ファイル処理では「開く」だけでなく「閉じる」までセットで覚えるのがとっても大切です。

クローズすると何が起きるの?
fclose は、ストリームとファイルを安全に切り離すために、いろいろやってくれます。
fclose が行う主なこと(イメージ)
| 処理 | 何が起きる? | なぜ必要? |
|---|---|---|
| フラッシュ | 書き込み待ちのデータをホスト環境へ引き渡す | 書いたはずの内容がファイルに残らない事故を防ぐ |
| 未読データの破棄 | 読み取り用に溜まっていた未処理データを捨てる | 中途半端な状態を残さない |
| 結び付きを解除 | ストリームをファイルから切り離す | これ以上そのストリームで操作しないため |
| バッファ解放 | 自動確保されたバッファを解放する | メモリや資源の無駄を防ぐ |
表の説明
- 「書き込み」はすぐにファイルへ直書きされず、途中で溜められることがあります(バッファリング)。
- fclose は最後にまとめて書き出すので、閉じ忘れると“保存したつもり”が消えることが起こり得ます。
- だから「開いたら閉じる」は、習慣として身につけるのが一番強いです。
図でつかむ:ファイルのクローズ
図:fopen で受け取った fp を fclose に渡すだけ
fp = fopen(ファイル名, モード);
↓
(読み書き)
↓
fclose(fp);
[ストリーム fp] ──X── [ファイル]
↑バッファは整理・解放
図の説明
- fopen が返してくれた FILE*(ここでは fp)が「操作の取っ手」です。
- クローズするときは、その取っ手をそのまま fclose に渡せばOK。
- クローズ後は fp が指していたストリームはもう使えません(使うと危険)。
fclose の書式(命令の形式)
書式
| 項目 | 内容 |
|---|---|
| ヘッダ | #include <stdio.h> |
| 形式 | int fclose(FILE *stream); |
| 引数 | stream:閉じたいストリーム(FILE*) |
| 返り値 | 成功:0 / エラー:EOF |
表の説明
- fclose は「成功か失敗か」を返してくれるので、必要ならチェックできます。
- 特に重要なデータを書き込む場面では、fclose の戻り値チェックが安心です。
サンプルプログラム
ファイルを開けたか確認して、開けたら閉じるプログラム例です。
プロジェクト名:chap13-3-1 ソースファイル名:chap13-3-1.c
Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。
Windows の Visual Studio が実行環境の場合、以下のパスに「data.txt」がない状態と配置した状態で実行結果を確認します。
C:\Users\joeac\source\repos\chap13-3-1\chap13-3-1
#include <windows.h>
#include <stdio.h>
int main(void)
{
SetConsoleOutputCP(65001); // 出力をUTF-8に設定
FILE *fp;
fp = fopen("data.txt", "r"); /* 読み取りモードでオープン */
if (fp == NULL) {
printf("data.txt を開けませんでした。ファイルがあるか確認してください。\n");
return 0;
}
printf("data.txt を開きました。いまからクローズします。\n");
if (fclose(fp) == 0)
printf("クローズ完了!後片付けもバッチリです。\n");
else
printf("クローズでエラーが起きました。\n");
return 0;
}このプログラムのポイント(文章で説明)
- fopen で data.txt を r(読み取り)で開きます
- 失敗したら fp は NULL なので、案内を表示して終了します
- 成功したら「開けたよ」と表示し、すぐ fclose(fp) で閉じます
- fclose の返り値を見て、クローズ成功かどうかをメッセージで分けています
- 「開いたら閉じる」の形が一番シンプルに確認できます
失敗時の分岐がなぜ大事?
ファイル処理は「失敗する可能性」が普通にあります。たとえば、
- ファイルが存在しない
- 権限がなくて開けない
- すでに別のプログラムがロックしている(環境による)
- ディスクやデバイスの問題
だから「fp が NULL だったらどうする?」を最初から書いておくと、プログラムが強くなります。
成功ルートと失敗ルート
fopen 成功 → fp は有効 → 読み書き → fclose
fopen 失敗 → fp は NULL → エラーメッセージ → 終了
説明
- 成功時だけ fclose を呼べばOKです(NULL を fclose に渡すのは危険なので避けます)。
- こういう分岐が「安全なファイル処理」の基本形になります。
「開く・閉じる」がセットな理由(バッファの話をやさしく)
ファイルに書く処理は、毎回すぐディスクへ書くとは限りません。
効率のために、いったんメモリ上のバッファに溜めて、まとめて書き出すことがあります。
図:書き込みがバッファに溜まってから保存されるイメージ
fprintf などで出力
↓
[バッファに一時保存] ← ここに残っていることがある
↓(fclose でフラッシュ)
[ファイルに反映]
図の説明
- fclose は「残っている分もちゃんと書いてね」という締めの処理をしてくれます。
- だから閉じ忘れると、最後の一部がファイルに残らないことがあります。
- 「処理が終わったら fclose」はデータ保護の意味でも重要です。
演習問題
演習13-1:ファイルの存在確認+クローズ確認
キーボードからファイル名を読み取り、そのファイルが開けるなら
そのファイルは開けました と表示し、必ず fclose で閉じる。
開けないなら そのファイルは開けません と表示するプログラムを作成せよ。
解答例
プロジェクト名:chap13-3-2 ソースファイル名:chap13-3-2.c
Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。
Windows の Visual Studio が実行環境の場合、以下のパスにファイルを配置します。
C:\Users\<ユーザー名>\source\repos\chap13-2-2\chap13-2-2
#include <windows.h>
#include <stdio.h>
int main(void)
{
SetConsoleOutputCP(65001); // 出力をUTF-8に設定
char name[256];
FILE *fp;
printf("確認したいファイル名を入力してください: ");
if (scanf("%255s", name) != 1) {
printf("入力を読み取れませんでした。\n");
return 0;
}
fp = fopen(name, "r");
if (fp == NULL) {
printf("そのファイルは開けません。\n");
return 0;
}
printf("そのファイルは開けました。\n");
if (fclose(fp) == 0)
printf("クローズも成功しました。\n");
else
printf("クローズでエラーが起きました。\n");
return 0;
}解説
- scanf でファイル名を受け取り、fopen(name, "r") を試します
- 成功したら fp は有効なので、fclose(fp) で後片付けします
- fclose の戻り値で「閉じる処理まで安全に終わったか」を確認できます
- この形は「存在確認」にもなります(開ける=少なくとも読み取りできる状態)
演習13-2:ファイルを空にしてから「消去しました」と表示
キーボードからファイル名を読み取り、そのファイルを空にする(中身を消去する)プログラムを作成せよ。
成功したら ファイルを空にしました と表示し、失敗したら 失敗しました と表示すること。
ヒント:書き込みモードでオープンするとよい。
解答例
プロジェクト名:chap13-3-3 ソースファイル名:chap13-3-3.c
Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。
Windows の Visual Studio が実行環境の場合、以下のパスにファイルを配置します。
C:\Users\<ユーザー名>\source\repos\chap13-2-3\chap13-2-3
#include <windows.h>
#include <stdio.h>
int main(void)
{
SetConsoleOutputCP(65001); // 出力をUTF-8に設定
char name[256];
FILE *fp;
printf("空にしたいファイル名を入力してください: ");
if (scanf("%255s", name) != 1) {
printf("入力を読み取れませんでした。\n");
return 0;
}
fp = fopen(name, "w"); /* w は長さ0にする(上書き開始) */
if (fp == NULL) {
printf("失敗しました。\n");
return 0;
}
if (fclose(fp) == 0)
printf("ファイルを空にしました。\n");
else
printf("クローズでエラーが起きました。\n");
return 0;
}解説
- w で開くと、既存ファイルは内容が消えて0からになります(新規作成にもなります)
- 開けたらすぐ閉じても、結果として「空ファイル」ができあがります。
- 重要ファイルに対して実行すると取り返しがつかないので、練習用のファイルで試すのが安全です。
