C 分段故障w/fwrite
我对C 分段故障w/fwrite,c,segmentation-fault,fwrite,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 Dat
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
原型,我觉得没问题
提前谢谢。可能发生的情况是: 调用
fgets()
或scanf()
将数据存储在结构Dati
之外。这将踩踏fp
指针变量,该变量很可能存储在堆栈帧上的Dati
之后。然后调用fwrite()
,该函数将取消引用fp
,并显示未定义的行为和分段错误
我敢打赌,如果你注释掉所有存储在Dati
中的scanf
和fgets
函数,并将它们替换为Dati
字段的硬编码赋值,你会发现崩溃已经修复。你的编译器(例如VC10@alk)不理解格式说明符中的'h'
,我相信,是一个C99添加。3种解决方案:
short
int i;
scanf("%d", &i);
Dati.Superati = i;
int
而不是short
,并使用%d
其他次要建议:
// @ 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
请参考以下讨论,可能您的系统很旧,不理解
%h..“
中的'h'
?什么操作系统?@Jeyaram我用fflush()只是为了尝试。我使用了一个在web上找到的_fflush()函数@chux我使用Windows 8,但在上一个Ubuntu中,代码不起作用。您是否已经完成了#include.h>
?否则可能会发生奇怪的事情。另外,它应该是int main
,但这不太可能导致您的问题。@ralph它可能会有帮助,但size\t fwrite(const void*restrict ptr、size\t size、size\t nmemb、FILE*restrict stream)
(nmemb
元素,其大小由size
指定)和OP似乎正确调用了它。对于样式:我建议fwrite(&Dati,sizeof Dati,1,fp)代码>,但这不是这里的主要问题。您在考虑哪个fgets()
或scanf()
?它们在我看来都很好,我认为它们很好。但我敢打赌,fp
被人踩了,这是我唯一认为有可能发生的事情。打得好。我就是这么想的。最后一个字段Crediti中的scanf
正在跺踏fp
,该字段很可能在堆栈帧中Crediti之后立即出现。
// @ 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