C语言结构体:如何将手动输入学生信息改为从指定格式文件加载
学生信息文件读取改造方案
整体改造逻辑
不需要改动原有Teacher/Student结构体定义、printT/printS打印逻辑、教师信息输入流程,仅替换原循环手动调用getS获取2个学生信息的代码块,核心是按照约定的3行/学生的格式从目标文件逐行读入数据,增加必要的容错判断。
分步实现流程
- 移除原逻辑中循环调用
getS等待终端输入学生信息的代码段 - 调用
fopen以只读模式打开指定的学生信息文件,必须校验文件打开状态,避免空指针读写触发程序崩溃 - 逐行解析文件内容,每3行内容组装为1个
Student结构体实例:- 第一行文本存储为学生姓名,注意处理行尾换行符
- 第二行整数存储为学生学习年份
- 第三行浮点数存储为学生分数
- 循环解析直到文件末尾,将解析完成的学生数据存入原有的学生数组,后续打印逻辑完全复用原有代码即可
可直接复用的代码段
// 替换原手动输入学生信息的代码段 FILE *fp_stu = fopen("student_info.txt", "r"); // 缺这行是新手调试最常踩的坑:文件不存在时直接读写指针会直接段错误退出 if (fp_stu == NULL) { perror("加载学生文件失败"); return 1; } // 按照原有代码中存储学生的数组大小定义容量,这里按最多存100个学生演示 Student stu_list[100]; int stu_total = 0; // 循环读直到文件结束或达到数组容量上限 while (stu_total < 100 && !feof(fp_stu)) { // 读姓名:用fgets读整行,避免scanf遇空格中断 char name_tmp[32] = {0}; if (fgets(name_tmp, sizeof(name_tmp), fp_stu) == NULL) break; // 手动去掉fgets读到的行尾换行符 name_tmp[strcspn(name_tmp, "\r\n")] = '\0'; strcpy(stu_list[stu_total].name, name_tmp); // 读学习年份,校验读入的字段数量 if (fscanf(fp_stu, "%d", &stu_list[stu_total].grade_year) != 1) break; // 读分数,校验读入的字段数量 if (fscanf(fp_stu, "%f", &stu_list[stu_total].score) != 1) break; // 跳过当前分数行读完残留的换行符,兼容Windows(\r\n)/Linux(\n)不同系统的换行格式 while (fgetc(fp_stu) != '\n' && !feof(fp_stu)); stu_total++; } fclose(fp_stu); // 后续直接用stu_list和stu_total调用原有的printS函数打印即可
高频调试问题定位
- 数据读取完全错位:读完整数/浮点数后没有跳过行尾的换行符,导致下一次
fgets直接读到空行,所有后续数据偏移 - 程序直接崩溃:没有判断
fopen的返回值,文件路径写错、文件不存在时直接操作空指针 - 姓名截断:读姓名的缓冲区长度小于实际内容长度,触发内存越界
- 读取数量比预期少:循环条件仅判断
feof没有加数组容量上限,遇到文件格式错误时触发数组越界
内容的提问来源于stack exchange,提问作者Patrik Cernay
相关产品推荐
相关产品推荐

