C语言使用fscanf读取结构体数组报错的正确解决方法
fscanf读取结构体数组报错修复方案
问题根因
你遇到的编译报错和运行异常来自4处写法错误:
- 结构体数组成员访问顺序错误:
mknpokok是长度为20的结构体数组,必须先通过[i]定位到第i个结构体元素,才能通过.访问内部成员。你写的mknpokok.nomor[i]属于非法访问,编译器会把mknpokok识别为结构体指针,才会抛出"是否要使用->"的报错。 - fscanf格式符错误:
%.3f是printf等输出函数用来控制小数位数的语法,fscanf做输入读取时不能加精度限定,直接用%f即可;另外你写的%[^\n]没有加长度限制,存在缓冲区溢出风险。 - 循环逻辑缺陷:
while(!feof(fp))的写法会在文件读取到末尾后多触发一次无效读取,容易写入脏数据或造成数组越界。 - 语法遗漏:fscanf语句末尾缺少分号,会直接触发编译错误。
修正后代码
首先确保循环计数器i初始值为0,文件指针fp已经通过fopen以可读模式正常打开,读取逻辑参考如下:
int i = 0; // 增加数组长度判断,避免读入数据超过数组容量 while (i < 20 && fscanf(fp, "\n%d %49[^\n] %d %f", &mknpokok[i].nomor, mknpokok[i].nama, &mknpokok[i].berat, &mknpokok[i].kalori) == 4) { // 此处可补充其他业务逻辑,比如计算totalkkal字段 i++; }
关键说明
- 结构体数组的成员访问固定格式为
数组名[索引].成员名,如果是指向结构体的指针才需要用->访问成员。 - 读字符串时用
%49[^\n]是因为nama数组长度为50,最多读取49个字符后自动追加字符串结束符\0,避免内存越界。 - 直接把fscanf的返回值作为循环判断条件:fscanf会返回成功匹配并赋值的字段个数,这里我们需要读4个字段,只有返回值等于4时才说明读取成功,从根源上避免
feof导致的多读问题。
内容的提问来源于stack exchange,提问作者LearnerC
相关产品推荐
相关产品推荐

