
C言語基礎|ファイルの中身の表示
「ファイルは“読む”だけで価値が出る。まずは中身をそのまま表示してみよう!」
キーボードから入力された文字を画面にそのまま出す、というプログラムは「入出力の基本」を学ぶのにちょうど良い練習でした。
でも、入力元をキーボードからファイルに変えるだけで、一気に実用感が出ます。
たとえば、設定ファイルの確認、ログの中身の表示、テキストの簡単な閲覧など、「ファイルの内容を表示する」だけで役立つ場面はたくさんあります。
この節では、ファイルを開いて、1文字ずつ読み取り、画面に出すという王道パターンを、丁寧に理解していきます。

何を作る?:ファイルを表示する最小の実用プログラム
ここでは、元の例(ファイル名を入力して全部表示)を少し変更して、よりシンプルにします。
- ファイル名はコマンドライン引数で受け取る(入力処理を簡単にする)
- 表示メッセージは英語にする
- コメントは日本語のまま
- 中身はそのまま標準出力に流す
サンプルプログラム
プロジェクト名:chap13-8-1 ソースファイル名:chap13-8-1.c
Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。
Windows の Visual Studio が実行環境の場合、以下のパスにファイルを保存します。
C:\Users\<ユーザー名>\source\repos\chap13-8-1\chap13-8-1
#include <stdio.h>
int main(int argc, char *argv[])
{
/* 引数チェック:ファイル名が指定されているか */
if (argc != 2) {
printf("Usage: showfile <filename>\n");
return 1;
}
/* ファイルを読み取りモードで開く */
FILE *fp = fopen(argv[1], "r");
if (fp == NULL) {
printf("ERROR: Could not open the file.\n");
return 1;
}
printf("---- File content start ----\n");
/* 1文字ずつ読み取って、そのまま出力する */
int ch;
while ((ch = fgetc(fp)) != EOF) {
putchar(ch);
}
printf("\n---- File content end ----\n");
/* ファイルを閉じる */
fclose(fp);
return 0;
}実行方法
コマンドライン引数を指定してプログラムを実行・デバッグするには、プロジェクトのプロパティ設定で引数を指定します。
1.プロパティ画面の左側のメニューから「構成プロパティ」→「デバッグ」を選択します。
2.右側の画面にある「コマンド引数」(またはCommand-line Arguments)の項目に、渡したい引数を入力します。
実行イメージ
たとえば、sample.txt が次の内容だったとします。
Hello
C file I/O!実行するとこうなります。
---- File content start ----
Hello
C file I/O!
---- File content end ----全体の流れを図でつかむ
図:ファイル → ストリーム → 画面
[ファイル sample.txt]
↓ fopen
[入力ストリーム fp]
↓ fgetc で1文字ずつ取り出す
[文字 ch(int)]
↓ putchar
[画面(stdout)]
図の説明
- fopen でファイルを開くと、ファイルに結び付いたストリーム fp ができます。
- fgetc(fp) がストリームから「次の1文字」を取り出します。
- 取り出した文字を putchar で画面に出せば、ファイルの中身が表示できます。
getchar と fgetc の違いがポイント
もともとの練習では getchar を使って「標準入力から1文字ずつ」取り出していました。
ファイルに変えるなら、同じ役割の関数が fgetc です。
getchar と fgetc の対応
| 関数 | どこから読む? | 引数 | 使いどころ |
|---|---|---|---|
| getchar | 標準入力 stdin | なし | キーボード入力を読む |
| fgetc | 任意の入力ストリーム | stream | ファイルなどから読む |
表の説明
- getchar は入力元が stdin に固定された fgetc だと考えるとスッキリします。
- fgetc(fp) の fp を stdin にすれば、実質 getchar と同じ流れになります。
fgetc の書式と戻り値(ここは超重要)
fgetc の書式
| 項目 | 内容 |
|---|---|
| ヘッダ | #include <stdio.h> |
| 形式 | int fgetc(FILE *stream); |
| 役割 | stream から次の1文字を読む |
| 返り値 | 読んだ文字(int)または EOF |
表の説明
- 返り値が int なのは、文字(0〜255)だけでなく EOF(通常 -1)も表したいからです。
- そのため、受け取る変数 ch は char ではなく int が基本です。
1文字ずつ読む while の意味
この部分が “ファイル表示の心臓” です。
図:while の判定
ch = fgetc(fp) → 文字なら ch に入る
ch が EOF でない → ループ継続
ch が EOF → ループ終了(ファイル終端 or 読み取りエラー)
図の説明
- ファイルの終わりに到達すると fgetc は EOF を返します。
- それを合図にループを抜けるので、「最後まで読む」処理が自然に書けます。
登場する命令(関数)の書式まとめ
fopen
| 項目 | 内容 |
|---|---|
| ヘッダ | #include <stdio.h> |
| 形式 | FILE *fopen(const char *filename, const char *mode); |
| 例 | fopen(argv[1], "r") |
| 失敗 | NULL |
fgetc
| 項目 | 内容 |
|---|---|
| ヘッダ | #include <stdio.h> |
| 形式 | int fgetc(FILE *stream); |
| 例 | ch = fgetc(fp) |
| 終了条件 | EOF |
putchar
| 項目 | 内容 |
|---|---|
| ヘッダ | #include <stdio.h> |
| 形式 | int putchar(int c); |
| 例 | putchar(ch) |
| 役割 | 1文字出力 |
fclose
| 項目 | 内容 |
|---|---|
| ヘッダ | #include <stdio.h> |
| 形式 | int fclose(FILE *stream); |
| 役割 | ストリームを閉じる |
表の説明
- ファイル入力の基本セットは fopen → fgetc → putchar → fclose です。
- まずこの流れが書けるようになると、次に「行数カウント」「文字種の集計」などへ自然に進めます。
演習問題
演習13-6:行数(改行数)を数える
ファイル名を指定して、そのファイル中の行数(改行文字の個数)を数えて表示せよ。
解答例
プロジェクト名:chap13-8-2 ソースファイル名:chap13-8-2.c
Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。
#include <stdio.h>
int main(int argc, char *argv[])
{
if (argc != 2) {
printf("Usage: countlines <filename>\n");
return 1;
}
FILE *fp = fopen(argv[1], "r");
if (fp == NULL) {
printf("ERROR: Could not open the file.\n");
return 1;
}
int ch;
long lines = 0;
/* 改行文字の数を数える */
while ((ch = fgetc(fp)) != EOF) {
if (ch == '\n') {
lines++;
}
}
fclose(fp);
printf("Line breaks: %ld\n", lines);
return 0;
}実行方法
コマンドライン引数を指定してプログラムを実行・デバッグするには、プロジェクトのプロパティ設定で引数を指定します。
1.プロパティ画面の左側のメニューから「構成プロパティ」→「デバッグ」を選択します。
2.右側の画面にある「コマンド引数」(またはCommand-line Arguments)の項目に、渡したい引数を入力します。
解説
- 改行の数を数えると「行数に近い値」が得られます。
- 最終行に改行が無い場合は、表示上の行数とずれることがある点も理解しておくと完璧です。
演習13-7:数字文字の個数を数える
ファイル中の数字文字 0〜9 の出現回数を数えて表示せよ。
解答例
プロジェクト名:chap13-8-3 ソースファイル名:chap13-8-3.c
Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。
#include <stdio.h>
int main(int argc, char *argv[])
{
if (argc != 2) {
printf("Usage: countdigits <filename>\n");
return 1;
}
FILE *fp = fopen(argv[1], "r");
if (fp == NULL) {
printf("ERROR: Could not open the file.\n");
return 1;
}
long digits = 0;
int ch;
/* '0' から '9' の範囲なら数字文字 */
while ((ch = fgetc(fp)) != EOF) {
if (ch >= '0' && ch <= '9') {
digits++;
}
}
fclose(fp);
printf("Digit characters: %ld\n", digits);
return 0;
}実行方法
コマンドライン引数を指定してプログラムを実行・デバッグするには、プロジェクトのプロパティ設定で引数を指定します。
1.プロパティ画面の左側のメニューから「構成プロパティ」→「デバッグ」を選択します。
2.右側の画面にある「コマンド引数」(またはCommand-line Arguments)の項目に、渡したい引数を入力します。
解説
- 文字コード上で '0'〜'9' が連続していることを利用しています。
- 1文字ずつ読む基本パターンが、そのまま集計処理に応用できるのが分かります。
