使用fscanf将文本文件内容读取到结构体时程序崩溃的原因排查
代码崩溃原因分析
问题代码
#include <stdio.h> #include <stdlib.h> typedef struct Student{ char nume[30]; char prenume[30]; float medie; }Student; int main() { FILE *st= fopen("input.txt","r"); Student a[10]; int i; for(i=0;i<10;i++) fscanf(st,"%s %s %f",a[i].nume,a[i].prenume,a[i].medie); fclose(st); return 0; }
问题描述
上述代码本应从文件中读取姓氏、名字和成绩数值,但运行时发生崩溃,请问原因是什么?
输入文件内容示例
ALEXANDRU Tudor 2.23 AMUZA Marius 2.15 CELCAN Alexandra 2.29 KONRAD Eric 2.15 ...
崩溃原因及修复方案
嗨,这是C语言里非常常见的细节错误,一眼就能定位问题:使用fscanf读取浮点数时没有传递变量的地址!
看你代码里的fscanf调用:
fscanf(st,"%s %s %f",a[i].nume,a[i].prenume,a[i].medie);
- 前两个
%s格式符没问题:a[i].nume和a[i].prenume是字符数组名,会自动隐式转换成指向数组首元素的指针,符合%s对参数类型的要求。 - 但第三个格式符
%f要求传入一个float*类型的指针,你直接传了a[i].medie这个float变量本身。这会让fscanf误以为这个变量的数值是要写入的内存地址,而这个地址几乎肯定是非法的(比如输入的2.23会被当成内存地址),程序试图往非法内存写数据,直接触发内存访问错误,导致崩溃。
修复方法
只需要给a[i].medie加上取地址符&,把变量的地址传给fscanf:
fscanf(st,"%s %s %f",a[i].nume,a[i].prenume,&a[i].medie);
额外优化建议
另外建议你加上文件打开失败的判断逻辑,如果input.txt不存在或者没有读取权限,fopen会返回NULL,后续操作也会出错:
FILE *st= fopen("input.txt","r"); if (st == NULL) { perror("Failed to open input file"); return EXIT_FAILURE; }
这样能让程序的鲁棒性更强,也能在文件出问题时给出明确的错误提示。
内容的提问来源于stack exchange,提问作者Stefan Nastase
相关产品推荐
相关产品推荐

