You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言如何读取.dat文件学生数据并拆分存入不同数组

C语言读取.dat学生答题数据拆分存储实现方案

核心存储结构定义

不需要零散给每道题单独建数组,用下标对齐的一维、二维数组存储即可,同一索引对应同一个学生的所有属性,后续判分遍历效率更高:

  • 姓名数组:char name[最大学生数][姓名最大长度],存每个学生的姓名字符串
  • 学号数组:char stu_id[最大学生数][学号最大长度],存每个学生的学号字符串
  • 答案二维数组:char ans[最大学生数][选择题总数],其中ans[i][j]代表第i个学生第j道题的作答结果,天然适配逐题比对标准答案的判分需求
  • 额外定义一个计数器,记录实际读取到的学生总数,避免遍历数组时读到未赋值的空数据

读取与拆分代码实现

直接用fopen、fscanf按固定格式匹配读取即可,不需要手动做字符串分割,注意做好异常校验:

#include <stdio.h>
#include <stdlib.h>

// 常量定义,后续调整题量、学生上限直接改这里就行
#define MAX_STU_NUM 100
#define MCQ_TOTAL 10
#define NAME_MAX_LEN 20
#define ID_MAX_LEN 10

int main() {
    // 初始化存储数组
    char name[MAX_STU_NUM][NAME_MAX_LEN];
    char stu_id[MAX_STU_NUM][ID_MAX_LEN];
    char ans[MAX_STU_NUM][MCQ_TOTAL];
    int stu_cnt = 0;

    // 打开文件,必须做返回值校验
    FILE *fp = fopen("stu_data.dat", "r");
    if (fp == NULL) {
        perror("文件打开失败");
        exit(EXIT_FAILURE);
    }

    // 循环读取直到文件结束或达到存储上限
    while (stu_cnt < MAX_STU_NUM) {
        // 先读取姓名、学号两个无空格字符串
        int read_ret = fscanf(fp, "%s %s", name[stu_cnt], stu_id[stu_cnt]);
        // 读不到2个字段说明到文件尾/数据格式损坏,直接跳出循环
        if (read_ret != 2) break;

        // 逐道读取选择题答案
        for (int q_idx = 0; q_idx < MCQ_TOTAL; q_idx++) {
            // 注意%c前面必须加空格:自动跳过所有空白符(空格、换行、制表符),避免把间隔符读成答案
            read_ret = fscanf(fp, " %c", &ans[stu_cnt][q_idx]);
            if (read_ret != 1) {
                fprintf(stderr, "第%d位学生答题数据缺失\n", stu_cnt + 1);
                fclose(fp);
                exit(EXIT_FAILURE);
            }
            // 可选:校验答案合法性,只允许A/B/C/D
            if (ans[stu_cnt][q_idx] < 'A' || ans[stu_cnt][q_idx] > 'D') {
                fprintf(stderr, "第%d位学生第%d题答案非法\n", stu_cnt + 1, q_idx + 1);
                fclose(fp);
                exit(EXIT_FAILURE);
            }
        }

        // 如果你的数据中学生记录之间用中文分号之类的非空白分隔符(比如示例里john记录后接;Paul),在这里加一行读走分隔符即可:
        // fscanf(fp, " %*c"); // %*c表示读入一个字符但不存储,自动跳过前面的空白

        stu_cnt++;
    }
    fclose(fp);

    // 后续判分逻辑示例
    char standard_ans[MCQ_TOTAL] = {'A','C','D','B','C','A','B','D','C','A'}; // 替换成实际标准答案
    int score[MAX_STU_NUM] = {0};
    for (int i = 0; i < stu_cnt; i++) {
        for (int q = 0; q < MCQ_TOTAL; q++) {
            if (ans[i][q] == standard_ans[q]) {
                score[i] += 10; // 按每题分值累加即可
            }
        }
        // 按需求输出结果即可
        printf("姓名:%s 学号:%s 成绩:%d\n", name[i], stu_id[i], score[i]);
    }

    return 0;
}

关键避坑点

  • 读取单个字符答案时,fscanf的格式串里%c前必须加空格,否则会把答案之间的空格、行尾换行符当成有效答案读入,直接导致所有答案错位。
  • 所有字符串数组的长度要比实际最长内容多1位,预留C语言字符串必需的结束符\0位置,避免出现内存越界。
  • 必须校验fscanf的返回值,遇到文件损坏、格式不符的情况直接终止,不要让脏数据流入后续判分逻辑。
  • 不需要为每道选择题单独创建数组,二维数组的索引访问方式写判分逻辑更简洁,后续调整题量只需要修改常量定义即可,不用改一堆数组声明。

内容的提问来源于stack exchange,提问作者Rafsan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:33:22