第49回
ユーティリティを作る~文字列置換プログラム

ファイルのオープン~openfile関数

入力ファイルをオープンするopenfile関数を作りましょう。ファイルをオープンする処理は、ほかのプログラムでもほぼ同じパターンで処理できるため、一度作ればいろいろと流用できます。

関数の仕様

関数の仕様を考えます。基本的な動作は以下のようになるでしょう。

(1)引数にファイル名とファイルモードを受け取る
(2)ファイルがオープンできればFILE構造体へのポインタを返す。
  オープンできなければNULLを返し、エラーメッセージを表示する

この関数のプロトタイプ宣言は
FILE * openfile(char *name, char *mode);
という形になります。

コードは非常に単純で、引数に受け取ったファイルをfopen関数でオープンし、FILE構造体へのポインタを返します。fopen関数でエラーが発生すればNULLポインタが返ってくるので、それをそのまま関数の戻り値にできます。

エラーメッセージの表示

単純にfopen関数を呼び出すだけなら、わざわざ別関数とする必要はありません。この関数では、ファイルがオープンできなかったときにエラーメッセージを表示します。

メッセージの表示には、printf関数を使うのが一般的です。しかし、printf関数は標準出力に文字列を出力するため、プログラムの出力がリダイレクトされるとエラーメッセージまでリダイレクト先に送られてしまいます。

エラーメッセージは、どのようなときでもディスプレイに表示されなければなりません。そのためには、メッセージを『標準エラー出力』へ送り出す必要があります。

標準出力以外にメッセージを出力するには、出力先を指定できるfprintf関数を使います。fprintf関数の引数は
  出力先, 書式指定文字列, 変数リスト…
となっており、第1引数で出力先を指定する以外は、printf関数とまったく同じです。

標準エラー出力はstderrという識別名で指定できます。仮にfnameがファイル名(の文字列を示すポインタ)だとすると、以下のようにしてエラーメッセージを出力します。
fprintf(stderr, "Can not open %s.¥n", fname);

これで、openfile関数はリスト1のように記述できます。

リスト1:ファイルをオープンするopenfile関数
FILE * openfile(char *name, char *mode)
{
  FILE    *fp;

  if ((fp = fopen(name, mode)) == NULL)
      fprintf(stderr, "Can not open ¥'%s¥'.¥n", name);
  return (fp);
}