K&Rを読もう(3) 1.5(1) catを作ろう。再帰と関数のネストのテストも兼ねて。

またまた定番。catを作ろうのコーナー。

定番過ぎるので、再帰と関数のネストを使ってみました。

バリバリgccオンリーのCコードデス。

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int (*f)(int) = putchar;
    
    void read_char(void)
    {
        int c;
        if ((c = getchar()) != EOF) {
            f(c);
            return read_char();
        } else
            return;
    }

    read_char();
    exit(EXIT_SUCCESS);
}

コンパイルとテスト。

% gcc -Wextra -O2 -o cat 1.5.1.c
% ./cat
Hello, K&R cat world!!
Hello, K&R cat world!!

スコープの確認も出来ました。

ま、普通のcatですね・・・。

演習 1-6

括弧を除くと、111...最後が0であることが確認できた。よく忘れるので注意したい。

演習 1-7

EOFを印字せよ。

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int (*middle_f)(int);
    int (*end_f)(int);

    void read_char(void)
    {
        int c;
        if ((c = getchar()) != EOF) {
            middle_f(c);
            return read_char();
        } else {
            end_f(c);
            return;
        }
    }

    int print_eof(int c)
    {
        return printf("EOF -- getchar returned %d --\n", c);
    }

    middle_f = putchar;
    end_f = print_eof;

    read_char();
    exit(EXIT_SUCCESS);
}

middle_f,end_fを定義した。

% gcc -Wextra -O2 -o cat ex-1-7.c
% ./cat
test
test
EOF -- getchar returned -1 --

EOFが-1であることも確認できた。詳しくは、man readcharか、/usr/include/stdio.h

/* End of file character.
   Some things throughout the library rely on this being -1.  */
#ifndef EOF
# define EOF (-1)
#endif

(-1)となってる理由がイマイチ不明。