scanf() the Bastard

When you first learn the C language, and you’re practicing basic input/output, you become familiar with the two I/O workhorses of the C library: printf() and scanf(). Of the two, printf() is my favorite. The scanf() function is highly useful, and it’s a great learning tool, but it’s not the best function for reading in a string of text.

The scanf() function scans formatted input. It uses the same placeholders, or conversion characters, as the printf() function. So when your code desires an unsigned int value, you use the %u and scanf() grabs only that value. In fact, it diligently rejects any non unsigned int value. (That’s a feature that can throw off some programmers.)

When used with the %s placeholder, scanf() reads in strings — but only up until the first white space character. That limits scanf()‘s definition of a string, which is frustrating.

#include <stdio.h>

int main()
{
    char name[64];
    char color[24];

    printf("Your first and last name: ");
    scanf("%s",name);
    printf("Your favorite color: ");
    scanf("%s",color);

    printf("%s's favorite color is %s.\n",
        name,
        color);

    return(0);
}

If you type in and run the above code, you may experience the following indigestion while running the program:

Your first and last name: Dan Gookin
Your favorite color: Dan's favorite color is Gookin.

Because the text Dan Gookin contains a space, the scanf() function stops reading after the first word, Dan. The rest of the text remains in the input stream, where it’s read by the second scanf() function and assigned to the color variable. The output is predicatble — but only if you’re familiar with the nature of the scanf() function.

Can you work around this limitation?

No!

Don’t even try to fake out scanf() and attempt to read in more text or avoid the issue. You can’t modify input nor can you fool the function in other ways.

Now I’ve read that some compliers may allow the * wildcard to be inserted into the %s placeholder. That trick doesn’t work on any of my machines, therefore I wouldn’t rely upon it for squat.

If you really need to read in a full string of text, then use a proper function. For example, the fgets() function can read text from the input stream. You can read about this function in my books, as well as my June 1, 2013 Lesson.

Leave a Reply