考试系统结对编程(2452116+2452127)
简易在线考试系统——结对编程实验报告
2452116 杨思哲
2452127 周添驭
一.算法设计思路
1.1 系统整体架构
系统采用模块化设计,分为三大核心模块:
题目管理模块(管理员模式):支持单选、多选、判断题的增删改查。
考生答题模块:实现限时答题、实时保存答案。
自动判分模块:考试结束后立即计算得分,生成含错题解析的成绩报告。
1.2 数据结构设计
定义 Question 结构体存储每道题的信息:
typedef struct {
int id; // 题目编号
QType type; // 题型:0单选 1多选 2判断
char text[256]; // 题干
char options[512]; // 选项文本
char answer[20]; // 标准答案(多选如"ABC")
int score; // 分值
char explanation[256]; // 解析
} Question;
全局数组 questions[] 存储所有题目,q_count 记录题目数量。
数据持久化使用二进制文件 questions.dat,便于快速读写。
1.3 关键算法
(1)实时保存答案
每答完一题,立即将 (题目ID, 考生答案) 追加写入临时文件 temp_answers.dat。即使程序意外终止,已答答案也不会丢失。
(2)限时控制
利用 time(NULL) 获取考试开始时的绝对时间戳,每显示一题前计算 difftime(now, start),若超过预设时长(如1800秒)则强制交卷,无需多线程。
(3)多选题判分
由于考生可能以不同顺序输入选项(如 "BCA" 与 "ABC"),我们采用排序后比较的方法:
将考生答案和标准答案的字符串分别按字符升序排序。
比较排序后的字符串是否相等。
该方法忽略顺序,准确判断选项集合是否一致。
(4)自动生成成绩报告
遍历所有题目,逐题比较正误,记录错题及解析,累加得分,最后输出 report.txt 文件。
二.程序代码





三.运算结果
3.1管理员添加题目

3.2考生答题

3.3生成的成绩报告

四.体会
1.2452116杨思哲的体会:
在本次实验中,我们先进行了充分的方案讨论,共同分析了需求,决定使用纯C语言开发,并确定了数据存储采用二进制文件、实时保存答案使用追加写入、限时功能借助标准库 time.h、多选题判分采用排序后比较忽略选项顺序等核心设计。讨论阶段让我们对整体架构有了统一认识,也提前发现了可能的问题(如字符串换行符处理、删除题目后ID重排等)。分工时,我负责编写全局数据(Question结构体、questions数组、q_count等)、所有辅助函数(loadQuestions、saveQuestions、realtimeSaveAnswer、loadTempAnswers、compareMultiAnswer)以及管理员模式下的全部函数(adminMode、addQuestion、deleteQuestion、modifyQuestion、listQuestions),搭档则负责编写主函数main和考生模式下的考试与判分模块(examMode、autoJudge)。
进入编码阶段后,我们严格按照结对编程流程交换角色。第一轮由我编码实现全局数据、辅助函数和管理员函数,搭档在旁边实时审核。搭档在审核中指出了我写的loadTempAnswers函数中fscanf可能因格式问题导致读取错误,并建议增加ID范围的判断,我立即修改完善;同时搭档还提醒在deleteQuestion函数中删除题目后应重新整理ID以避免空洞,我也及时补充了ID重排逻辑。第二轮交换角色,由搭档编码实现主函数和考生模式模块,我负责审核。我在审核时发现搭档的autoJudge函数中最初没有计算满分值,导致报告中的满分显示错误,我指出后他立即补充了fullScore的累加;另外在主函数的菜单循环中,我建议加入默认分支处理无效输入,搭档也采纳并修改。我们还共同完成了集成测试,模拟了限时交卷、多题型答题等场景,最终所有功能正常运行。
通过这次结对编程,我深刻体会到两人协作对代码质量的提升效果。实时审核能快速发现低级错误和设计缺陷,交换角色则让我和搭档都熟悉了全部代码逻辑,知识互补明显。虽然过程中需要更多沟通和协调,但相比单人开发后反复调试,总体效率反而更高。同时我也认识到本次实验的局限性——没有图形界面、不支持随机抽题或多考生并发,但这些可以作为后续改进的方向。总之,结对编程不仅是一种高效的开发方式,更是一次宝贵的团队合作体验,感谢搭档的默契配合。
2.2452127周添驭的体会:
一、第三部分:考生模式与判分函数 算法设计思路
我负责的考生答题模块(examMode)和自动判分模块(autoJudge)是系统的核心交互与结果输出模块,核心目标是实现限时答题、实时保存答案、自动判分、生成错题解析报告,算法设计严格围绕需求,兼顾稳定性、实用性和用户体验。
- examMode () 函数算法设计思路
核心功能
控制考生完整考试流程:校验题库→初始化答题环境→限时答题→逐题展示与答案录入→实时保存→自动交卷。
算法流程(分步逻辑)
前置校验:首先检查全局题目数量q_count,若为 0 直接提示 "题库为空,无法考试",终止流程,避免无效操作。
环境初始化:清空上一次考试的临时答案文件temp_answers.dat(以写入模式打开再关闭即可清空),保证本次考试答案独立。
计时启动:调用time(NULL)获取系统当前时间,赋值给start变量,作为考试起始时间基准。
逐题答题循环
遍历每一道题目(从第 1 题到最后 1 题);
限时判断:每次答题前获取当前时间now,用difftime(now, start)计算已用秒数,若超过设定时限TIME_LIMIT_SEC(30 分钟),立即终止循环,强制交卷;
题目展示:根据题目类型(单选 / 多选 / 判断),格式化输出题干、选项、分值,清晰展示给考生;
答案录入:接收考生输入的答案,做基础格式校验(非空、符合选项规则);
实时保存:调用realtimeSaveAnswer()函数,将题目 ID 和答案立即写入临时文件,防止断电 / 程序崩溃丢失答案。
交卷判分:答题循环结束(答完所有题 / 超时),调用autoJudge()函数执行自动判分。
算法核心设计点
无多线程限时:基于系统时间差判断,轻量无复杂度,适配基础编程环境;
实时保存:逐题追加写入文件,不覆盖历史答案,数据安全性高;
容错处理:题库为空、答题超时等异常场景都做了流程拦截。 - autoJudge () 函数算法设计思路
核心功能
读取考生答案→自动判分→统计总分→生成带错题解析的report.txt报告。
算法流程(分步逻辑)
加载答案:调用loadTempAnswers()函数,从临时文件中读取所有考生答案,按题目 ID 存入二维数组。
初始化变量:定义总分变量total_score=0,计算试卷满分full_score(遍历所有题目分值累加)。
打开报告文件:以写入模式创建report.txt,用于存储考试结果。
逐题判分循环
遍历每一道题目,匹配对应考生答案;
分类判分:
✅ 判断题 / 单选题:直接用strcmp()字符串比较考生答案与标准答案;
✅ 多选题:调用compareMultiAnswer()函数,排序后比较(忽略选项顺序);
结果处理:
✔ 答对:累加该题分值到total_score,记录 "答题正确";
✔ 答错:不加分,记录考生答案、标准答案、题目解析,形成错题明细。
生成报告:将考试标题、逐题答题结果、总分、满分统一写入报告文件。
输出提示:关闭文件后,在控制台打印考生最终总分。
算法核心设计点
分类判分逻辑:适配单选 / 多选 / 判断三种题型,符合考试规则;
错题闭环:自动关联解析,让考生知道错误原因;
数据闭环:从临时文件读取答案,最终输出可视化报告,流程完整。
二、第四部分:主控函数 算法设计思路
main () 函数算法设计思路
核心功能
程序入口,负责加载初始数据、展示主菜单、调度功能模块、控制程序生命周期。
算法流程(分步逻辑)
数据初始化:程序启动后,第一时间调用loadQuestions(),从questions.dat二进制文件加载所有题目到内存数组,保证后续所有模块能读取最新题库。
主菜单循环:无限循环展示主菜单,直到用户选择退出:
打印菜单选项:1 - 管理员模式、2 - 考生模式、0 - 退出系统;
接收用户输入的选择指令;
模块调度:
输入 1 → 调用adminMode()进入管理员题目管理模块;
输入 2 → 调用examMode()进入考生考试模块;
输入 0 → 退出循环,终止程序;
循环返回:每个子模块执行完毕后,自动返回主菜单,支持用户连续操作。
算法核心设计点
单一入口:所有功能从主菜单调度,代码结构清晰,易维护;
数据预加载:启动即加载题库,避免重复读取文件,提升效率;
流程可控:循环菜单提升用户体验,支持反复操作。
三、结对编程作业体会
本次简易在线考试系统的结对编程作业,让我对团队协作、模块分工、代码联调有了非常直观且深刻的理解,收获远超独立完成作业。
在分工上,我负责考生答题、自动判分和主控函数模块,搭档负责题目管理模块。我们首先统一了全局变量、结构体定义和文件交互规则,确保两边代码能无缝对接 —— 这是结对编程最关键的一步,前期约定清晰,后期联调几乎没有出现数据冲突。
开发过程中,我们互相支撑、互补短板。搭档在文件读写、结构体操作上经验更丰富,帮我解决了临时答案文件读取、二进制文件同步的细节问题;我则梳理了考试流程的逻辑,优化了限时判断和多选题判分算法,让整个考试流程更流畅。我们会一起讨论核心逻辑,比如实时保存的机制、多选题忽略顺序判分的实现方案,两个人的思路碰撞,让代码更严谨、更贴合需求。
联调阶段是最大的考验,我们把各自模块整合后,模拟了完整流程:管理员增删题目→考生考试答题→程序自动判分生成报告,逐一测试了限时交卷、实时保存、错题解析等功能,快速定位并修复了小 bug,这个过程让我明白代码不仅要能运行,还要能和团队代码完美配合。
通过这次作业,我不仅巩固了 C 语言文件操作、结构体、函数调用等知识点,更学会了规范编程、沟通协作、模块化设计。结对编程让我们互相监督、互相学习,减少了代码错误,也提升了开发效率。这次经历让我体会到,在实际开发中,团队协作能力和编程能力同样重要,这是课堂之外非常宝贵的收获。
浙公网安备 33010602011771号