はじめての C

C programming note*1
関数 carte() を より 一般的な かたちに 改良していきます。

int carte(FILE *fp)
{
char buf[MAX_SIZE];

while (fgets(buf, MAX_SIZE, fp) != NULL) {
remove_pre_blank(buf);
remove_pos_blank(buf);
center(buf, width);
if (fputs(buf, stdout) == EOF) {
fprintf(stderr, "ce3r: write error\n");
return -1;
}
}
return 0;
}

carte() 関数の 中で fputs() が 書くのに 失敗したら、stdout に エラーメッセージを 出すだけでなく、return で carte() 関数から 戻っている。 そのファイルの 残りの行は 処理しないわけだ。

(つまり) 書くことができない 事態なのだから、処理は そこで 打ち切りたい。 他の 入力ファイルを 処理し始めても きっと ムダに なるからだ。

fputs() は、エラーが 起きると EOF を 返し、そうでなければ 0 を 返します (K&R 2nd p201)。

(以前 つくったものと) 異なる点として、carte() 関数が "void" ではなく "int" と 定義されている点が あげられる。 これは carte() 関数が 値を 返すように するためだ。

さて、関数が 値を 返すのに return 文を 使う。 void 型の (値を 返さない) 関数では、return 文は ただ "return" と 書いてあって、その時点で その関数を 終了するための 文になる。

一方、それ以外の 型の (値を 返す) 関数では、return の後ろに 戻り値を 指定するのだ。 この carte() 関数では、エラーが あったときに "-1" を、正常に ファイルを 処理し終わったら "0" を 返すように なっている。(p149)

当然、carte() を 呼び出す側の main() 関数の コードにも 変更が 加えられます。

main(int argc, char **argv)
{
FILE *fp;
int r;

......


if (argc == 0) {
if (carte(stdin) != 0)
return 1;
}
else {
while (argc--) {
if )((fp = fopen(*argv, "r"))( == NULL)
cant(*argv); /* no return */
r = carte(fp);
fclose(fp);
if (r != 0)
return 1;
argv++;
}
}
return 0;
}

main() の中で carte() を 呼び出している 箇所では、この関数が 返してくる 値を 見て エラーが あったかどうかを 判断している。 もし エラーが あったら、その後の ファイルの 処理も 行なわないで*2 main() 関数を return 1 で 抜け出している。(p149)

*1:「作ってわかる Cプログラミング」

*2:必要なくなるので