Exercise 4.7 - Function ungets that will push back an entire string onto the input

Question

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?

/**
 * Exercise 4.7 of The C Programming Language by Brian Kernighan and Dennis
 * Ritchie
 *
 * 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?
 *
 */

#include <stdio.h>
#include <string.h>

#define BUFSIZE 100
#define MAXLINE 1000

char buf[BUFSIZE];
int bufp = 0;

int getch(void);
void ungetch(int);
void ungets(char s[]);
int mgetline(char s[], int lim);

int main(int argc, char *argv[]) {
    char line[MAXLINE];
    int len;

    while ((len = mgetline(line, MAXLINE)) > 0) {
        ungets(line);
        while ((len = mgetline(line, MAXLINE)) > 0) {
            printf("%s", line);
        }
    }
    return 0;
}

int mgetline(char s[], int lim) {
    int c, i;

    for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i) {
        s[i] = c;
    }
    if (c == '\n') {
        s[i] = c;
        ++i;
    }
    s[i] = '\0';
    return i;
}

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;
    }
}

void ungets(char s[]) {
    int len = strlen(s);
    while (len > 0) {
        ungetch(s[--len]);
    }
}

Explanation

This program defines ungets(s), which takes a string as an input and and removes one character at a time from the back of the string and puts them into a the buffer BUF. It does this, till all the characters from the input string are placed onto the buffer. It uses the function ungetch to place to the buffer.

When getch() is called, the characters from the buffer are read first and it is output on the screen.

So, when we write something like this.

$ ./a.out
this is a sentence
this is a sentence

The first sentence is read as input and placed in the BUF and the next sentence is read using getch() from the BUF array.

Visualize It

Try It