Search code examples
ccharscanfwhitespace

how to understand scanf buffer and format in C?


I vaguely remember having trouble with scanf and today I met this phenomenon again. I guess it's a well known problem(?). This is a simple test code to test scanf.

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>

int8_t buff[1024];

int main()
{
    char option;

    printf("Welcome to the demo of character device driver...\n");

    while (1) {
        printf("***** please enter your option *****\n");
        printf("           1. Write                 \n");
        printf("           2. Read                  \n");
        printf("           3. Exit                  \n");
        scanf("%c", &option);    // line 18
        printf("your option = %c\n", option);
        switch(option) {
            case '1' :
                printf("Enter the string(with no space) :\n");
                //scanf("%[\t\n]s", buff);
                scanf("%s", buff);    // line 24
                break;
            case '2' :
                printf("Data = %s\n", buff);
                break;
            case '3' :
                exit(1);
                break;
            default :
                printf("Enter valid option. option = %c\n", option);
        }
    }
}

When I run it(I used debugger to track it), when scanf("%c", &option); in line 18 runs the second time, the '\n' character left out from the last scanf("%s", buff); in line 24 is input, making option \n and the switch statement prints the complaint about the option and skips to the while loop.
I observed that if I change scanf("%c", &option); to scanf(" %c", &option);, the problem is gone. How should I understand this phenomenon? What effect does it have to have a space or a tab before %c or %s when using scanf function?


Solution

  • From the C Standard (7.21.6.2 The fscanf function)

    5 A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read.

    Thus using a format with leading white-spaces as in this call of scanf

    scanf(" %c", &option);
    

    results in skipping white spaces in the input stream buffer.