K&R C Programs Exercise 4-7

Exercise 4-7. Write a routine ungets(s) that will push back an entire string onto the input. Should ungets know about buf and bufp, or should it just use ungetch?

The answer is: ungets should use ungetch, not access buf and bufp directly. This is the principle of information hidinggetch 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 primitivesungets is entirely implemented in terms of ungetch; 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

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>