Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scanf returns 0 without waiting for input

Tags:

c

stdin

scanf

I have never programmed in C and today I have to write small code. Program is very easy - I want to add two integers. But when I'm trying to check if given input is a number and first scanf returns 0, the second one returns 0 too without waiting for input. Code:

int main()
{
    int a = 0;
    int b = 0;
    printf("Number a:\n");
    if (scanf("%d", &a) != 1)
    {
        printf("Not a number. a=0!\n");
        a = 0;
    }
    printf("Number b:\n");
    if (scanf("%d", &b) != 1)
    {
        printf("Not a number. b=0!\n");
        b = 0;
    }
    printf("%d\n", a+b);
    return 0;
}
like image 347
Koli96 Avatar asked Oct 31 '25 02:10

Koli96


2 Answers

The input that failed to convert to a number for the first fscanf() is still pending in standard input's buffer and causes the second fscanf() to fail as well. Try discarding offending input and re-prompting the user:

#include <stdio.h>

int main(void) {
    int a = 0;
    int b = 0;
    int c;
    printf("Number a:\n");
    while (scanf("%d", &a) != 1) {
        printf("Not a number, try again:\n");
        while ((c = getchar()) != EOF && c != '\n')
            continue;
        if (c == EOF)
            exit(1);
    }
    printf("Number b:\n");
    while (scanf("%d", &b) != 1) {
        printf("Not a number, try again:\n");
        while ((c = getchar()) != EOF && c != '\n')
            continue;
        if (c == EOF)
            exit(1);
    }
    printf("%d\n", a + b);
    return 0;
}

Factorizing the code with a utility function makes it much clearer:

#include <stdio.h>

int get_number(const char *prompt, int *valp) {
    printf("%s:\n", prompt);
    while (scanf("%d", valp) != 1) {
        printf("Not a number, try again:\n");
        while ((c = getchar()) != EOF && c != '\n')
            continue;
        if (c == EOF)
            return 0;
    }
    return 1;
}

int main(void) {
    int a, b;

    if (!get_number("Number a", &a) || !get_number("Number b", &b)) {
         return 1;
    }
    printf("%d\n", a + b);
    return 0;
}
like image 167
chqrlie Avatar answered Nov 01 '25 20:11

chqrlie


That is because, once the first scanf() failed, it is probably because of matching failure, and the input which caused the matching failure, remains inside the input buffer, waiting to be consumed by next call.

Thus, the next call to scanf() also try to consume the same invalid input residing in the input buffer immediately, without waiting for the explicit external user input as the input buffer is not empty.

Solution: After the first input fails for scanf(), you have to clean up the input buffer, for a trivial example, something like while (getchar() != '\n'); should do the job.

like image 30
Sourav Ghosh Avatar answered Nov 01 '25 19:11

Sourav Ghosh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!