Fgets влияет на вывод - PullRequest
0 голосов
/ 08 ноября 2018

Я с трудом пытаюсь выяснить, почему мой последний fgets (), кажется, удаляет значение в "studente [0] .nome", в то время как при использовании scanf () этого не происходит, поэтому Я был бы рад, если бы кто-то мог объяснить мне проблему и дать мне новую возможность учиться. Заранее спасибо.

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;
}

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

из 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.

когда вы объявляете этот массив

struct studenti studente[N_STUDENTI];

Вы выделяете порции ниже сегментов памяти, где matricola составляет всего около 3 байтов, что фактически означает, что вы можете поместить туда только 2 допустимых байта ..

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

однако с нижней строкой есть все шансы, что вы прочитаете, что находится за вашей границей, и фактически испортите соседние куски

fgets(matricola, 4, stdin);
0 голосов
/ 08 ноября 2018

Вы делаете

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

Но определение matricola равно

char matricola[3];

Это означает, что вы можете выйти за пределы массива и иметь неопределенное поведение .

При использовании fgets с массивами (не указателями), всегда используйте sizeof, чтобы получить размер:

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

Таким образом, вы всегда будете передавать правильный размер.

И, конечно, у вас возникает та же проблема после цикла при чтении в автономный массив matricola.

Если вам действительно нужна трехсимвольная строка, то вам нужно увеличить размер до 4 (чтобы соответствовать нулевому ограничителю). Если вам нужна строка символов четыре , то размер должен быть 5.

...