K&R 演習4-9 解答 (プログラミング言語C 第2版)

スポンサーリンク

鍛錬 838

K&R 演習4-9 解答 (プログラミング言語C 第2版)

われわれの getch と ungetch では,押し戻された EOF が正しく扱えない。EOF が戻されたときにはどうすればよいかを考え,その設計に従ってプログラムを書け。

B.W.カーニハン D.M.リッチー 石田晴久 訳 『プログラミング言語C 第2版 ANSI 規格準拠』, (共立出版, 2017), pp.97.

 
スポンサーリンク

プログラム

以下は、EOF が押し戻された場合に対応したプログラム、kr_4_9.c です。

pp.97 の時点でまだ登場していないライブラリ関数などはできる限り使用しないようにし、本書中で作成した関数を使用するようにしています。
記述方法(「 char *s 」または「 char s[] 」など)についても、できる限り pp.97 時点での記載通りにしています。

// include
#include <stdio.h>
#include <ctype.h>

// preprocessor
#define BUFSIZE 100		// 入力文字を押し戻す際に利用するバッファのサイズ

// prototype
int getch(void);
void ungetch(int);

// variable
char buf[BUFSIZE];	// ungetch()用のバッファ
int bufp = 0;		// バッファbufにおける次の空き位置

// main
int main(void)
{
	int c;
	
	printf("size of EOF    --> %ld\n", sizeof(EOF));
	printf("size of buf[0] --> %ld\n", sizeof(buf[0]));
	putchar('\n');
	
	c = 'C';
	ungetch(c);
	c = EOF;
	ungetch(c);
	c = 'B';
	ungetch(c);
	c = 'A';
	ungetch(c);
	
	while ((c = getch()) != EOF) {
		putchar(c);
	}
	
	return 0;
}

// =================================================
// @brief  1文字を取得する
// @param  無し
// @return buf[--bufp] -> バッファに押し戻された文字
// @return getchar() -> 入力された1文字
// @note   無し
// =================================================
int getch(void)
{
	return (bufp > 0) ? buf[--bufp] : getchar();
}

// ============================================
// @brief  文字を入力に戻す(バッファに格納する)
// @param  c [in],入力に戻す文字
// @return 無し
// @note   無し
// ============================================
void ungetch(int c)
{
	if (bufp >= BUFSIZE) {
		printf("ungetch: too many characters\n");
	}
	else if (c == EOF) {
		printf("ungetch: EOF can't be buffered\n");
	}
	else {
		buf[bufp++] = c;
	}
}

実行結果

以下は、プログラム kr_4_9.c を実行しています。

***@ubuntu:~/***/test/c$ 
***@ubuntu:~/***/test/c$ gcc -Wall -Wextra kr_4_9.c -o kr_4_9
***@ubuntu:~/***/test/c$ ./kr_4_9
size of EOF    --> 4
size of buf[0] --> 1

ungetch: EOF can't be buffered
ABC