What’s Next, Keyboard?

Suppose you must write code that remains busy while checking to see whether a key has been pressed. The program repeats a loop, performing various tasks, but eager for that key press. When a key is pressed, the code fetches the key. Two things stand in your way to make this happen.

First, standard input is streaming. True, input can be buffered or unbuffered, but it all comes in the stream not directly from the keyboard.

Second, C library functions that read standard input are blocking calls. They wait for input, pausing the entire program.

The process I’m referencing is called polling. Activity takes place, such as in a loop, and certain conditions are checked. If one of these conditions is whether a key has been pressed on the keyboard, how can you check it without pausing the entire program?

While it may seem impossible to perform a “just checking” routine on standard input, it can be done. But first I must present a silly example.

2024_03_23-Lesson-a.c

#include <stdio.h>

int main()
{
    char a;

    a = 'A';
    while(1)
    {
        printf(" %c",a++);
        if( a=='Z' )
            a = 'A';
    }

    return 0;
}

This code builds a program that continuously outputs uppercase letters A through Z. As it doesn’t do anything else, it runs fast, spewing the alphabet all over the terminal window. Press Ctrl+C to terminate it.

The program’s endless while loop should have a terminating condition, but it’s anticipated that the loop terminates when the user presses a key. The problem is how to implement this condition without halting the program?

To prove that it can’t work (at least for now), the following update to the code calls the getchar() function. This function is one way to check on the keyboard, but it halts the entire program:

2024_03_23-Lesson-b.c

#include <stdio.h>

int main()
{
    char a;

    a = 'A';
    while(1)
    {
        printf(" %c",a++);
        if( a=='Z' )
            a = 'A';
        /* terminate on key */
        if(getchar())
            break;
    }

    return 0;
}

When the getchar() function is encountered, the loop stops to wait for keyboard input. In fact, the loop runs only once. This code is a poor example of polling.

One solution is to check standard input at a low level. For next week’s Lesson, I show how to access the standard input device in this manner. But other solutions exist as well. For example, network programming involves a lot of polling. I cover these other solutions as I continue to explore checking the keyboard for input.

Leave a Reply