Search code examples
arrayscscanf

Why does my program exit after scanf("%i", x);, where x is int x;


My code stops taking input after the second score and ends execution. I can't think of any reason why it might be doing that below code takes first and second score inputs from me, skips the third, and ends execution without going further.

This below C code stops taking input after the second and exits. It accepts the first and second input, skips the third, and exits.

How do I resolve this error? Below is my provided code.

#include <stdio.h>
int main(void)
{
    int scores[3];
    int x;
    int y;
    int z;
    printf("first score is:\n");
    scanf("%i", x);
    scores[0] = x;
    printf("second score is:\n");
    scanf("%i", y);
    scores[1] = y;
    printf("third score is:\n");
    scanf("%i", z);
    scores[2] = z;
    printf("average is %f\n", (scores[0]+scores[1]+scores[2])/(float)3);
}

Solution

  • You need to pass the address of a variable to scanf in order for it to work correctly. As a pointer is an integer type, passing an integer instead of a pointer can "work" but leads to undefined behaviour. Compiling with warnings on should tell you this. If I compile your code with -Wall -Wextra I see several, including warnings about the argument type passed to scanf.

    If I further add -Werror then warnings get treated as errors and I have to fix this before my code will compile into something I can run. Suggestion: fix the first error/warning first and then recompile.

    test.c:9:17: warning: format specifies type 'int *' but the argument has type 'int' [-Wformat]
        scanf("%i", x);
               ~~   ^
    test.c:12:17: warning: format specifies type 'int *' but the argument has type 'int' [-Wformat]
        scanf("%i", y);
               ~~   ^
    test.c:15:17: warning: format specifies type 'int *' but the argument has type 'int' [-Wformat]
        scanf("%i", z);
               ~~   ^
    test.c:9:17: warning: variable 'x' is uninitialized when used here [-Wuninitialized]
        scanf("%i", x);
                    ^
    test.c:5:10: note: initialize the variable 'x' to silence this warning
        int x;
             ^
              = 0
    test.c:12:17: warning: variable 'y' is uninitialized when used here [-Wuninitialized]
        scanf("%i", y);
                    ^
    test.c:6:10: note: initialize the variable 'y' to silence this warning
        int y;
             ^
              = 0
    test.c:15:17: warning: variable 'z' is uninitialized when used here [-Wuninitialized]
        scanf("%i", z);
                    ^
    test.c:7:10: note: initialize the variable 'z' to silence this warning
        int z;
             ^
              = 0
    6 warnings generated.
    

    Correcting that:

    #include <stdio.h>
    
    int main(void)
    {
        int scores[3];
        int x;
        int y;
        int z;
        printf("first score is:\n");
        scanf("%i", &x);
        scores[0] = x;
        printf("second score is:\n");
        scanf("%i", &y);
        scores[1] = y;
        printf("third score is:\n");
        scanf("%i", &z);
        scores[2] = z;
        printf("average is %f\n", (scores[0]+scores[1]+scores[2])/(float)3);
    }
    

    Of course, x, y, and z are redundant.

    #include <stdio.h>
    
    int main(void)
    {
        int scores[3];
    
        printf("first score is:\n");
        scanf("%i", &scores[0]);
    
        printf("second score is:\n");
        scanf("%i", &scores[1]);
    
        printf("third score is:\n");
        scanf("%i", &scores[2]);
    
        printf("average is %f\n", (scores[0]+scores[1]+scores[2])/(float)3);
    }
    

    You should be checking the scanf returns 1 each time, indicating it has successfully read one value. If not, you should take some action, as otherwise you are working with uninitialized data, meaning your program could print anything.

    Further, when you are dealing with arrays, repeating your code to read multiple values is a waste. Use a loop.

    #include <stdio.h>
    #include <stdlib.h>
    
    #define ARR_SIZE 3
    
    int main(void)
    {
        int scores[ARR_SIZE];
    
        for (size_t i = 0; i < ARR_SIZE; i++) {
            printf("Score %d is:\n", i);
            if (scanf("%d", &scores[i]) != 1) {
                printf("Invalid input\n");
                exit(EXIT_FAILURE);
            }
        }
    
        int sum = 0;
    
        for (size_t i = 0; i < ARR_SIZE; i++) {
            sum += scores[i];
        }
    
        printf("Average is %f\n", sum/(float)ARR_SIZE);
    }