Back to main

Why is input so difficult in C?

Problems

As we mentioned in Why are we learning C, the C language is fairly low-level: it deliberately mimics the way that computer architectures work. This is a good idea when the programmer must optimize every aspect of the program (15-30 years ago), or in understanding how the hardware works (your 2nd year "system architecture" course). But this causes problems when non-experts try to build useful or interesting programs.

In order to simplify input and output, the C language treats everything as a file. This produces smaller executables and requires less work to port the language to a new computer architecture, but it means that the computer does not do certain automatic checks.


For example, when the computer executes scanf("%i", &x); it will look for an int in the stdin (standard input) "file". If it does not find an int, the function will return a 0. The function will not advance beyond the point of incorrect input -- C does not make assumptions about what you, the programmer, wants to do. If the programmer wants to skip over the non-int data, then the programmer is expected to know how to do this.


A famous problem in C is memory management. C does not try to take care of memory for you; it does exactly what the programmer tells it to do. This is unfortunate when reading text from the keyboard -- as we see in Lab 5, text is an array of characters. If nothing tells the computer to stop reading text from the keyboard, it will continue to read text from the keyboard, merrily replacing vital system information with the text it reads from the keyboard.

However, this is not the only problem. We can limit the number of characters with scanf("%4s", text);. However, this means that anything over 4 characters will still be in the keyboard buffer -- scanf will not remove any extra characters from the buffer. We must do that manually.

Some websites recommend using one of these:
fflush(NULL)
fflush(stdin)
However, fflush is intended for output streams. It is not guaranteed to clear an input stream like stdin.

Reading text safely

Limit the number of characters, and clear the keyboard buffer after reading a string:

#include <stdio.h>

// you're not expected to understand this.
void clearKeyboardBuffer() {
    char ch;
    while ((ch = getchar() != '\n') && (ch != EOF));
}

int main() {
    char text[5];
    printf("Enter some text (4 chars max):\n");
    scanf("%4s", text);
    printf("You typed: %s\n", text);

    clearKeyboardBuffer();

    printf("Again:\n");
    scanf("%4s", text);
    printf("You typed: %s\n", text);
}
Note that this is one of the few times that you will see a while (...); loop (with a semicolon ; at the end, instead of a code block { ... }.

Check if the input was an integer:

#include <stdio.h>

// you're not expected to understand this.
void clearKeyboardBuffer() {
    char ch;
    while ((ch = getchar() != '\n') && (ch != EOF));
}

int main() {
    int x;
    int was_int;

    printf("Please enter an integer: \n");
    was_int = scanf("%i", &x);
    while (!was_int) {
        printf("That wasn't an integer!");
        printf("  Try again: \n");
        clearKeyboardBuffer();
        was_int = scanf("%i", &x);
    }
    printf("Thanks, your int was %i.\n", x);
}

Creative Commons LicenseUnless otherwise noted, all materials on these pages are licenced under a Creative Commons Licence.