Exercise 4-7. Write a routine
ungets(s)that will push back an entire string onto the input. Shouldungetsknow aboutbufandbufp, or should it just useungetch?
The answer is: ungets should use ungetch, not access buf and bufp directly. This is the principle of information hiding — getch and ungetch own the buffer; callers use the interface. Pushing back a string means pushing its characters in reverse order so that they come back out in forward order (last pushed = first read).
/* K&R Exercise 4-7 — ungets: push an entire string back onto input
* Compile: gcc -ansi -Wall ex4-7.c -o ex4-7 */
#include <stdio.h>
#include <string.h>
#define BUFSIZE 100
static char buf[BUFSIZE];
static int bufp = 0;
int getch(void)
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
void ungetch(int c)
{
if (bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}
/* Push back string s — characters pushed in reverse so they read forward */
void ungets(const char s[])
{
int i = strlen(s);
while (i > 0)
ungetch(s[--i]);
}
int main(void)
{
int c;
ungets("hello");
printf("reading back: ");
while ((c = getch()) != EOF && c != '\n' && c != '\0')
putchar(c);
putchar('\n'); /* hello */
ungets("world");
ungets("! "); /* pushes '!' then ' ', so reads '! world' */
printf("reading back: ");
while ((c = getch()) != EOF && c != '\n' && c != '\0')
putchar(c);
putchar('\n'); /* ! world */
return 0;
}
Compile and Run
gcc -ansi -Wall ex4-7.c -o ex4-7
./ex4-7
Sample Output
reading back: hello reading back: ! world
The second example shows push-back stacking: ungets("world") pushes d l r o w, then ungets("! ") pushes ' ' '!' on top. Reads come out ! world.
Why Use ungetch and Not Direct Buffer Access?
If ungets manipulated buf and bufp directly, it would need to know the buffer’s internal layout — creating a hidden coupling. If the buffer representation ever changed (e.g., circular buffer, different size), ungets would break too. Using ungetch as the sole write interface means only one function needs to change if the implementation changes.
What This Exercise Teaches
- Information hiding — callers use the interface (
ungetch), not the internals (buf,bufp) - Reverse push for forward read — pushing characters in reverse is the key insight; the buffer is LIFO
- Composing from primitives —
ungetsis entirely implemented in terms ofungetch; no duplication of buffer logic
Set Up Your C Environment
← Exercise 4-6 |
Chapter 4 Solutions |
Exercise 4-8 →
Book: The C Programming Language, 2nd Ed — Kernighan & Ritchie
1 comment on “K&R C Programs Exercise 4-7”