C言語入門|文字コードとファイル形式の基本

ファイルに触る前に知っておきたい考え方

「よし、次はファイルに書き込みだ!」
そう思いたくなるところですが、その前にひとつ大事な考え方があります。

それが ストリーム です。

C言語では、ファイルを直接ゴリっと一気に読み書きする、という発想はあまりしません。
プログラムと外部の世界との間で、データが少しずつ流れる道 を用意して、そこを通してやりとりを行います。

この「データの通り道」がストリームです。

ストリームとは何か

ストリームとは、
プログラムと外部(ファイル・画面・キーボードなど)をつなぐ、データの流れ
のことです。

イメージとしては、次のように考えるとわかりやすいです。

  • 外部にあるファイルや装置が上流
  • プログラムが下流
  • データが少しずつ流れてくる小さな川

なぜ少しずつ処理するのか

ファイル入出力では、次のような事情があります。

問題内容
メモリ制限ファイルはメモリより大きい場合がある。
効率必要な分だけ処理したほうが無駄が少ない。
安定性少量ずつ処理すればエラーに強い。

そこで、

  • 読み取りも
  • 書き込みも

少しずつ流す仕組み が必要になります。
これを実現するのがストリームです。

プログラム外部とのデータのやりとり

プログラムが扱うデータは、必ずしもファイルだけではありません。

実は、次のようなものもすべてストリームの接続先と考えられます。

接続先役割
キーボード入力ストリーム
ディスプレイ出力ストリーム
ファイル入出力ストリーム
通信回線入出力ストリーム

C言語では、
「どこから来たデータか」より「どのストリームから来たか」
という考え方をします。

この統一された発想のおかげで、
ファイル入力も画面出力も、似た書き方で扱えるのです。

標準入出力という特別なストリーム

C言語プログラムでは、main関数が始まった瞬間から、
特別な3つのストリームがすでに用意されています。

それが 標準入出力 です。

C言語の3つの標準ストリーム

名称stdio.hでの名前デフォルトの接続先
標準入力stdinキーボード
標準出力stdoutディスプレイ
標準エラー出力stderrディスプレイ

これらは 自分でopenしなくても使える、とても便利なストリームです。

すでに使っている標準入出力

実は、これまでの学習で、あなたはすでに標準ストリームを使いこなしています。

printf の役割

printf は、
標準出力ストリームにデータを書き込む関数 です。

つまり、

  • printf で出力した文字は
  • stdout を通って
  • ディスプレイに表示される。

という流れになっています。

scanf の役割

scanf は、
標準入力ストリームからデータを読み取る関数 です。

  • キーボードから入力された文字が
  • stdin を通って
  • プログラムに届く

というわけです。

これまで当たり前のように使ってきた関数も、
実はストリームを介した入出力だったのです。

標準エラー出力の存在意義

標準エラー出力 stderr は、
エラーメッセージ専用のストリームです。

stdout と同じディスプレイに表示されることが多いですが、
役割ははっきり分かれています

ストリーム用途
stdout正常な出力
stderrエラーメッセージ

この分離のおかげで、

  • 正常な出力だけをファイルに保存する。
  • エラーは画面に表示する。

といった制御が可能になります。

標準入出力の接続先は変えられる

多くのOSでは、プログラム起動時に、

  • stdin → キーボード
  • stdout → 画面
  • stderr → 画面

という接続が自動で行われます。

しかし、
リダイレクト というOSの機能を使うと、この接続先を変更できます。

たとえば、

  • 標準出力をファイルにつなぐ
  • 標準入力をファイルから読む

といったことが可能です。

C言語側のコードは一切変えなくても、
入出力の向きだけを変えられるのは、
ストリームという考え方のおかげです。

この章で扱うこと

この先の章では、

  • ファイルにつながるストリームを開く方法
  • ファイルから読み取る方法
  • ファイルへ書き込む方法

を、順番に解説していきます。

今はまず、

C言語では、入出力はすべてストリームを通して行われる

という考え方を、しっかり頭に入れておいてください。