Home > database >  Reading from scanf results to infinite loop
Reading from scanf results to infinite loop

Time:10-28

I'm trying to read information about students using scanf() in a for loop (N times -> N inputted by the user), but the for() loop goes more than that... it doesn't stop at all. I've tried all the combinations for the string formatting, but nothing seems to work.

This is my code:

#include <stdio.h>
#include <string.h>

typedef struct STUDENT_CONSTRUCTOR {
    char first_name[35], last_name[35];
    char gender;
    int grade;
} student;

int main(void) {
    int N; // number of entries

    student list[N];

    printf("Number of entries: "); scanf("%d", &N);

    for (int i = 0; i<N; i  ) {
        printf("<Entry %d>\n", i);
        scanf("%d %c %s %s\n", &list[i].grade, &list[i].gender, list[i].first_name, list[i].last_name);
    }
    return 0;
}

What I want to type in are sequences like the following: 10 M Mateas Mario, where "10" is the average grade, "M" the gender, "Mario" my first name and "Mateas", my last name.

N is properly read, and also the data inside the list[] array is properly read. list[] is based on a structure that holds all these data types.

Still, whenever I type in a specific value for N (for example 3, 4, 5, etc.), <Entry ...> always goes beyond that number. Before telling me that scanf() is deprecated, I would like to know if there's a possibility of fixing this code without getting rid of the scanf() function. I don't want to use fgets() because I don't know the maximum number of characters the input contains.

Any help would be appreciated. Thank you.

CodePudding user response:

Here ...

    int N; // number of entries

    student list[N];

... you are using the indeterminate initial value of N to specify the dimension of list. Undefined behavior results. That UB is not constrained to manifest as an immediate failure or a noisy one. In this particular case, it is manifesting as your iteration not stopping where you expect it to do.

Although it is not generally very fruitful to reason about the mechanism of a particular manifestation of UB, it nevetherless seems commonly to inspire some kind of perverse curiosity, so I will speculate that in your case, list is being given fewer elements than ultimately you request, maybe even 0, and as a result, your inputs are overrunning its bounds, causing the value of N to change unexpectedly.

Fix it by inputting N before the declaration of list, or else by just declaring list with a fixed number of elements large enough to accommodate every acceptable value of N.

CodePudding user response:

You have used the non-initialized variable N in a declaration of a variable length array

int N; // number of entries

student list[N];

So the program has undefined behavior.

Instead you need to write

int N; // number of entries

printf("Number of entries: "); scanf("%d", &N);

student list[N];

Also in the call of scanf remove the new line character '\n' from the format string

scanf("%d %c %s %s", &list[i].grade, &list[i].gender, list[i].first_name, list[i].last_name);

And instead of the function scanf you may use the function scanf_s.

  • Related