fgets 正在影响输出

fgets is influencing output

我很难弄清楚为什么我的最后一个 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;
}

你会

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

但是matricola定义是

char matricola[3];

这意味着您可以超出数组范围并具有 undefined behavior.

当对数组(不是指针)使用 fgets 时,总是使用 sizeof 来获取大小:

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

这样您将始终传递正确的尺寸。

当您读入独立数组 matricola.

时,在循环后当然会遇到同样的问题

如果您真的需要一个三字符的字符串,那么您需要将大小增加到 4(以适应空终止符)。如果需要4个字符串,那么大小应该是5.

来自 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 ('[=10=]') 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);