Exercise 4-8. Suppose that there will never be more than one character of pushback. Modify
getchandungetchaccordingly.
The original K&R implementation uses an array buf[BUFSIZE] and an index bufp to support multiple pushed-back characters. If only one character of pushback is ever needed, the array becomes unnecessary. A single static int buf suffices — initialized to EOF to mean “empty”. This is simpler, uses less memory, and makes the constraint explicit in the code.
Solution
/* K&R Exercise 4-8 — getch/ungetch with at most one character of pushback
* Compile: gcc -ansi -Wall ex4-8.c -o ex4-8 */
#include <stdio.h>
/* buf == EOF means the buffer is empty */
static int buf = EOF;
int getch(void)
{
int c = buf;
buf = EOF;
return (c != EOF) ? c : getchar();
}
void ungetch(int c)
{
buf = c; /* no bounds check needed — only one slot */
}
int main(void)
{
int c;
ungetch('X');
c = getch(); putchar(c); /* X */
c = getch(); putchar(c); /* reads from stdin */
putchar('\n');
return 0;
}
Before and After Comparison
| Version | Buffer | Capacity | Overflow handling |
|---|---|---|---|
| Original | char buf[100]; int bufp |
100 chars | Error message on overflow |
| Exercise 4-8 | int buf = EOF |
1 char | Silently overwrites (one-slot constraint is a precondition) |
Compile and Run
echo "hello" | gcc -ansi -Wall ex4-8.c -o ex4-8 && ./ex4-8
Sample Output
Xh
X comes from the pushed-back character; h is the first character from stdin (hello).
What This Exercise Teaches
- Right-sizing state — when you know a constraint will never be violated, you don’t need infrastructure to handle its violation; simpler code is often better code
- EOF as sentinel — using
EOF(-1) to mean “empty” works because all valid characters fit inunsigned char, which is whybufmust beint, notchar - Same interface, simpler internals —
getchandungetchhave identical signatures; callers need not change
Set Up Your C Environment
← Exercise 4-7 |
Chapter 4 Solutions |
Exercise 4-9 →
Book: The C Programming Language, 2nd Ed — Kernighan & Ritchie