如何在C语言中用fscanf将文件内容读取到结构体?读取失败求助
无法将文件中学生信息存入结构体的问题分析与修复
你的代码存在多个关键问题,导致无法正确读取文件内容到结构体,以下是具体问题和修复方案:
核心问题点
- 函数声明不匹配:开头的
readStudentsFromFile();等声明未指定参数和返回类型,与后续定义冲突,会引发编译错误。 - 结构体字段错误:
struct Student中的grade被定义为int grade[100];,但每个学生仅对应一个成绩,应改为int grade;。 - 文件读取逻辑错误:
- 统计行数时,
while(!feof(file))配合fgetc会导致行数多算一次(feof需读取到文件末尾后才会触发),且读完后文件指针停在末尾,后续fscanf无法读取内容。 fscanf参数错误:name、surname、number是字符数组名,本身就是指针,无需加&;若grade是单个int,需传递&var[i].grade。
- 统计行数时,
- 局部变量作用域问题:
readStudentsFromFile中定义的struct Student var[100]是局部变量,函数执行完毕后会被销毁,主函数中的var数组未被赋值,自然无法正确显示内容。 - 不安全的输入函数:
gets(fileName)存在缓冲区溢出风险,应使用fgets替代。 - count初始化错误:初始值设为1会导致空文件时行数统计错误,应从0开始。
修复后的代码
#include <stdlib.h> #include <string.h> #include <stdio.h> // 修正结构体,grade改为单个int struct Student { char name[100], surname[100], number[100]; int grade; }; // 正确声明函数,指定参数和返回类型 void readStudentsFromFile(struct Student students[], int *count); int main() { struct Student var[100]; int studentCount; readStudentsFromFile(var, &studentCount); // 测试打印读取到的学生信息 for(int i = 0; i < studentCount; i++){ printf("学生%d: %s %s, 学号:%s, 成绩:%d\n", i+1, var[i].name, var[i].surname, var[i].number, var[i].grade); } return 0; } void readStudentsFromFile(struct Student students[], int *count) { char fileName[100]; printf("Enter file name: "); // 用fgets替代gets,处理换行符 fgets(fileName, sizeof(fileName), stdin); fileName[strcspn(fileName, "\n")] = '\0'; // 去掉fgets读取的换行符 FILE *file = fopen(fileName, "r"); if (!file) { printf("Error: Unable to open file %s\n", fileName); *count = 0; return; } int i = 0; // 直接用fscanf读取,直到文件末尾,无需先统计行数 while (fscanf(file, "%s %s %s %d", students[i].name, students[i].surname, students[i].number, &students[i].grade) == 4) { i++; } *count = i; fclose(file); }
修复说明
- 将结构体的
grade改为单个int,匹配每个学生一个成绩的需求。 - 把主函数中的结构体数组传递给
readStudentsFromFile,直接在该数组中写入数据,避免局部变量销毁导致的数据丢失。 - 移除先统计行数的冗余逻辑,直接通过
fscanf的返回值判断读取是否成功,简化代码同时避免文件指针位置问题。 - 用
fgets替代gets,提升输入安全性,并处理换行符。 - 正确声明函数,指定返回类型和参数,消除编译错误。
内容的提问来源于stack exchange,提问作者Talha
相关产品推荐
相关产品推荐

