はじめての 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)