You need to enable JavaScript to run this app. C语言结构体:如何将手动输入学生信息改为从指定格式文件加载
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.03 21:24:03