具有fwrite的分段错误

时间:2014-09-11 16:15:46

标签: c segmentation-fault fwrite

我的fwrite函数存在问题(我在C :: B上使用调试检查了它)。 这是代码:

struct  studente
{   char Cognome_Nome[30];
    char Matricola [11];
    short Superati;
    float Media_Pesata;
    short Crediti;
};
typedef struct studente STUDENTE;

void main()
{   FILE *fp;
    STUDENTE Dati;

    if((fp = fopen("studente.dat","w+b")) == NULL)
        printf("Error\n");
    else
    {   fflush(stdin);
        printf("Inserire il cognome e nome: ");
        fgets(Dati.Cognome_Nome, 30, stdin);

        fflush(stdin);
        printf("\nInserire la matricola: ");
        fgets(Dati.Matricola, 11, stdin);

        fflush(stdin);
        printf("Inserire il numero di esami superati: ");
        scanf("%hd", &Dati.Superati);

        fflush(stdin);
        printf("Inserire la media pesata: ");
        scanf("%f", &Dati.Media_Pesata);

        fflush(stdin);
        printf("Inserire il numero di crediti: ");
        scanf("%hd", &Dati.Crediti);

        fwrite(&Dati, sizeof(STUDENTE), 1, fp);
    }
}

调用fwrite时收到分段错误。我无法理解问题出在哪里。我检查了fwrite原型,我认为没问题。

提前谢谢。

2 个答案:

答案 0 :(得分:1)

你的编译器(例如VC10 @alk)不理解格式说明符中的'h',我相信它是C99的补充。 3解决方案:

  1. 更改为新编译器。

  2. 通过临时变量阅读short

    int i;
    scanf("%d", &i);
    Dati.Superati = i;
    
  3. 制作2个字段int而不是short并使用"%d"

    struct  studente {
       ...
       int Superati;
       int Crediti;
    } 
    ...
    scanf("%d", &Dati.Superati);
    ...
    scanf("%d", &Dati.Crediti);
    

  4. 其他小建议:

    // @ Tom Tanner
    // void main()
    int main(void)
    
    // Avoid magic numbers
    // fgets(Dati.Cognome_Nome, 30, stdin);
    fgets(Dati.Cognome_Nome, sizeof Dati.Cognome_Nome, stdin);
    
    // @ Jeyaram
    // Do not use fflush(stdin). Better methods exist to handle stray input data
    // fflush(stdin);
    
    // Less error prone and easier to maintain code
    // fwrite(&Dati, sizeof(STUDENTE), 1, fp);
    fwrite(&Dati, sizeof Dati, 1, fp);
    
    // Check I/O function results
    

答案 1 :(得分:0)

可能发生的事情是:

fgets()scanf()的调用是在结构Dati之外存储数据。这会踩到fp指针变量,它可能会在Dati之后立即存储在堆栈帧上。然后,您致电fwrite()解除引用fp热潮您有未定义的行为和细分错误。

我敢打赌,如果您将所有存储到scanf的{​​{1}}和fgets函数注释掉,并将其替换为Dati字段的硬编码分配,您会看到崩溃是固定的。