The ungetc() Function

The standard C library contains a clutch of functions you use all the time, such as printf(), getchar(), malloc(), time(), rand(), and others. If you look in the library, you may discover some oddball functions that you’ve never used. One of those oddball functions might be ungetc().

The ungetc() function has been around since C was first introduced back in the 1970s. Due to this crustiness, you would think it serves some valuable, needed purpose. Even after reading the original K&R book, I can’t discern why the function was deemed important enough to be necessary. Anyway, it’s in the library.

The ungetc() function takes a single character and shoves it back onto an input stream. It’s sort of the opposite of the getc() function, which reads a single character from an input stream. And keep in mind that ungetc() is an input function, not an output function. Here’s the format:

int ungetc(int c, FILE *stream);

c is a character and stream is an open file or standard input (stdin). The value returned is the character ungetted or the EOF on an error.

Useful examples of how this function would be necessary are rare. Basically, whatever character you unget is read from the same stream by the next get function. The character you unget isn’t displayed, and it’s not saved to a file; remember that ungetc() is not an output function.

I crafted this sample code to kinda sorta show how ungetc() can work:

#include <stdio.h>

int main()
{
    ungetc('\n',stdin);
    ungetc('o',stdin);
    ungetc('l',stdin);
    ungetc('l',stdin);
    ungetc('e',stdin);
    ungetc('h',stdin);

    while(putchar(getchar()) != '\n')
        ;

    return(0);
}

Lines 5 through 10 unget a series of characters, stuffing them into the standard input stream.

Line 12’s while loop reads a character from standard input and then displays that character, up until the newline is encountered.

The effect of this code is to spew out a line of text as if it were generated by standard input:

hello

Characters are inserted (ungetted?) into the input stream in reverse order. The last character inserted is the first character read.

You can use the ungetc() function on an open file, but if you subsequently use a file position indicator manipulation function (fseek(), fsetpos(), or rewind()) the characters inserted into the stream are discarded.

Again, I can’t find any useful examples of how this function could be necessary, but I’m sure a need was present or Mr. Kernighan and Mr. Ritchie wouldn’t have sought to add the function to the standard C library.

Leave a Reply