Alessandro Floris
Alessandro Floris

Reputation: 3

fgets is influencing output

I'm having an hard time trying to figure out why my last fgets() seems to delete the value into "studente[0].nome", meanwhile when i use the scanf() that doesn't happen, so I would love if someone could explain me the problem and give me a new opportunity to learn. Thanks in advance.

struct studenti
{
    char nome[40];
    char cognome[40];
    short voto;
    char matricola[3];
};

#define N_STUDENTI 1

int main(void)
{
struct studenti studente[N_STUDENTI];
//float media = 0.0f;
char matricola[3];

printf("Inserisci i dati degli studenti nel Db:\n");

for(short i = 0;i<N_STUDENTI;i++)
{
    printf("Studente %d\n", i+1);
    fputs("NOME:", stdout);
    fgets(studente[i].nome, 40, stdin);
    fputs("COGNOME:", stdout);
    fgets(studente[i].cognome, 40, stdin);
    fputs("NUMERO MATRICOLA:", stdout);
    fgets(studente[i].matricola, 4, stdin);
    fputs("VOTO:", stdout);
    scanf("%hu", &studente[i].voto);
    getchar();
}

/* */
puts("INSERISCI MATRICOLA DELLO STUDENTE: ");
fgets(matricola, 4, stdin);//**HERE IS THE PROBLEM**
//whith a getcahr() works
printf("\n*NOME*: %s*", studente[0].nome);

return 0;
}

Upvotes: 0

Views: 43

Answers (2)

Some programmer dude
Some programmer dude

Reputation: 409176

You do

fgets(studente[i].matricola, 4, stdin);

But the matricola definition is

char matricola[3];

That means you can go out of bounds of the array and have undefined behavior.

When using fgets with arrays (not pointers) then always use sizeof to get the size:

fgets(studente[i].matricola, sizeof studente[i].matricola, stdin);

That way you will always pass the correct size.

And of course you have the same problem after the loop when you read into the stand-alone array matricola.

If you really need a three-character string then you need to increase the size to 4 (to fit the null-terminator). If you need a four character string, then the size should be 5.

Upvotes: 1

asio_guy
asio_guy

Reputation: 3767

from fgets()

  fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s.  Reading stops after an EOF  or  a  new-
   line.  If a newline is read, it is stored into the buffer.  A terminating null byte ('\0') is stored after the last character in the buffer.

when you are declaring this array

struct studenti studente[N_STUDENTI];

you are allocating chunks of below memory segments where matricola is only about 3 bytes, which actually means you can put only 2 legal bytes in there..

{
    char nome[40];
    char cognome[40];
    short voto;
    char matricola[3];
};

however with below line there is every chance that you read past what your boundary is and actually corrupt neighboring chunks

fgets(matricola, 4, stdin);

Upvotes: 0

Related Questions