老师在教学过程中,会经常以试卷的形式来检验学生的学习情况。现在由你来帮助老师设计一个试卷自动生成系统,完成从已有题库(题库包含2个文件,1个是选择题题库文件,1格式填空题题库文件)中随机提取指定题目书的题目生成一份新的试卷。该系统生成的试卷中只有2种题型:单项选择题、填空题(只有一个空)。其中
单项选择题包括题目编号、题目、选项A、选项B、选项C、选项D、答案
填空题包括题目编号、题目、答案
功能:
(1)试题添加:向试题库追加写入一道新的题目,要求题目编号自动生成,且与已存题目的编号不重复;所有内容不能为空。即不断充实题库;
(2)试题删除:通过题目编号进行题目的删除,如果删除成功则提示删除成功,否则提示删除失败;
(3)备份全部题目;
(4)删除全部题目;
(5)试题修改:通过题目编号查找对应题目,并修改指定的题目的内容,注意不是修改题目的全部内容,而是可以针对性的修改局部内容;
(6)试题查询:通过题目编号查询指定的题目的所有内容;
(7)统计共有多少道题目;
(8)查询题目中含有某个特定内容(用户输入)的所有题目内容;
(9)自动随机生成由单项选择题、填空题合在一起的试卷及标准答案2个文件(exam.txt和answer.txt),各题型的题目数由用户输入。注意选择题和填空题的题目数可以不一样;要求每次生成的试卷题目、顺序都不能完全相同。也就是要求真正的随机提取题目。
(10)以上功能要求通过菜单的方式进行操作;要求对相应内容进行必要的合法性检查。本题要求用链表实现。要求具有良好的人机交互界面。每个题型要提前录入至少10道题。
#include
#include
#include
// 选择题结构体
typedef struct ChoiceQuestion {
int id; // 题目编号
char question[1000]; // 题目
char optionA[200]; // 选项A
char optionB[200]; // 选项B
char optionC[200]; // 选项C
char optionD[200]; // 选项D
char answer; // 答案
} ChoiceQuestion;
// 填空题结构体
typedef struct FillQuestion {
int id; // 题目编号
char question[1000]; // 题目
char answer[50]; // 答案
} FillQuestion;
// 选择题链表结点
typedef struct ChoiceNode {
ChoiceQuestion data; // 选择题数据
struct ChoiceNode *next; // 下一个选择题结点
} ChoiceNode;
// 填空题链表结点
typedef struct FillNode {
FillQuestion data; // 填空题数据
struct FillNode *next; // 下一个填空题结点
} FillNode;
// 选择题链表
typedef struct ChoiceList {
ChoiceNode *head; // 选择题链表头结点
ChoiceNode *tail; // 选择题链表尾结点
int size; // 选择题链表中的结点数
} ChoiceList;
// 填空题链表
typedef struct FillList {
FillNode *head; // 填空题链表头结点
FillNode *tail; // 填空题链表尾结点
int size; // 填空题链表中的结点数
} FillList;
// 创建选择题链表
ChoiceList *createChoiceList() {
ChoiceList *list = malloc(sizeof(ChoiceList));
list->head = list->tail = NULL;
list->size = 0;
return list;
}
// 创建填空题链表
FillList *createFillList() {
FillList *list = malloc(sizeof(FillList));
list->head = list->tail = NULL;
list->size = 0;
return list;
}
ChoiceList *readChoiceQuestionFile(const char *fileName, ChoiceList *list) {
FILE *fp = fopen(fileName, "r");
if (fp == NULL) {
printf("文件打开失败\n");
return list;
}
while (!feof(fp)) {
ChoiceQuestion question;
int readNum = fscanf(fp, "%d %s %s %s %s %s %s", &question.id, question.question, question.optionA, question.optionB,
question.optionC, question.optionD, &question.answer);
if (readNum != 7) {
break;
}
ChoiceNode *node = malloc(sizeof(ChoiceNode));
node->data = question;
node->next = NULL;
if (list->tail == NULL) {
list->head = list->tail = node;
} else {
list->tail->next = node;
list->tail = node;
}
list->size++;
}
fclose(fp);
return list;
}
FillList *readFillQuestionFile(const char *fileName, FillList *list) {
FILE *fp = fopen(fileName, "r");
if (fp == NULL) {
printf("文件打开失败\n");
return list;
}
while (!feof(fp)) {
FillQuestion question;
int readNum = fscanf(fp, "%d %s %s", &question.id, question.question, question.answer);
if (readNum != 3) {
break;
}
FillNode *node = malloc(sizeof(FillNode));
node->data = question;
node->next = NULL;
if (list->tail == NULL) {
list->head = list->tail = node;
} else {
list->tail->next = node;
list->tail = node;
}
list->size++;
}
fclose(fp);
return list;
}
ChoiceNode *findChoiceNode(ChoiceList *list, int index) {
if (index < 0 || index >= list->size) {
return NULL;
}
ChoiceNode *node = list->head;
int i;
for (i = 0; i < index; i++) {
node = node->next;
}
return node;
}
void swapChoiceNodes(ChoiceList *list, int i, int j) {
if (i < 0 || i >= list->size || j < 0 || j >= list->size) {
return;
}
// 如果i和j相等,则不用交换
if (i == j) {
return;
}
// 查找结点i和结点j
ChoiceNode *nodeI = findChoiceNode(list, i);
ChoiceNode *nodeJ = findChoiceNode(list, j);
// 交换结点i和结点j的数据
ChoiceQuestion temp = nodeI->data;
nodeI->data = nodeJ->data;
nodeJ->data = temp;
}
FillNode *findFillNode(FillList *list, int index) {
if (index < 0 || index >= list->size) {
return NULL;
}
FillNode *node = list->head;
int i;
for (i = 0; i < index; i++) {
node = node->next;
}
return node;
}
void swapFillNodes(FillList *list, int i, int j) {
if (i < 0 || i >= list->size || j < 0 || j >= list->size) {
return;
}
// 如果i和j相等,则不用交换
if (i == j) {
return;
}
// 查找结点i和结点j
FillNode *nodeI = findFillNode(list, i);
FillNode *nodeJ = findFillNode(list, j);
// 交换结点i和结点j的数据
FillQuestion temp = nodeI->data;
nodeI->data = nodeJ->data;
nodeJ->data = temp;
}
void shuffleChoiceQuestions(ChoiceList *list) {
int i;
for (i = 0; i < list->size; i++) {
int j = rand() % list->size;
// 交换结点i和结点j的位置
swapChoiceNodes(list, i, j);
}
}
void shuffleFillQuestions(FillList *list) {
int i;
for (i = 0; i < list->size; i++) {
int j = rand() % list->size;
// 交换结点i和结点j的位置
swapFillNodes(list, i, j);
}
}
void generateExam(ChoiceList *choiceList, FillList *fillList, int choiceNum, int fillNum) {
// 随机打乱选择题和填空题的顺序
shuffleChoiceQuestions(choiceList);
shuffleFillQuestions(fillList);
// 将选择题和填空题写入试卷
FILE *examFile = fopen("exam.txt", "w");
if (examFile == NULL) {
printf("试卷文件打开失败\n");
return;
}
int i;
int number = 1;
// 将选择题和填空题写入试卷
ChoiceNode *choiceNode = choiceList->head;
for (i = 0; i < choiceNum; i++) {
fprintf(examFile, "%d. %s ", number++, choiceNode->data.question);
fprintf(examFile, "A. %s ", choiceNode->data.optionA);
fprintf(examFile, "B. %s ", choiceNode->data.optionB);
fprintf(examFile, "C. %s ", choiceNode->data.optionC);
fprintf(examFile, "D. %s\n", choiceNode->data.optionD);
choiceNode = choiceNode->next;
}
FillNode *fillNode = fillList->head;
for (i = 0; i < fillNum; i++) {
fprintf(examFile, "%d. %s\n", number++, fillNode->data.question);
fillNode = fillNode->next;
}
fclose(examFile);
// 将标准答案写入标准答案文件
FILE *answerFile = fopen("answer.txt", "w");
if (answerFile == NULL) {
printf("标准答案文件打开失败\n");
return;
}
choiceNode = choiceList->head;
for (i = 0; i < choiceNum; i++) {
fprintf(answerFile, "%c\n", choiceNode->data.answer);
choiceNode = choiceNode->next;
}
fillNode = fillList->head;
for (i = 0; i < fillNum; i++) {
fprintf(answerFile, "%s\n", fillNode->data.answer);
fillNode = fillNode->next;
}
fclose(answerFile);
}
void addChoiceQuestion(ChoiceList *list, ChoiceQuestion question) {
// 寻找下一个可用的序号
int currentIndex = 1; // 声明并初始化当前序号
while (findChoiceNode(list, currentIndex) != NULL) {
currentIndex++;
}
currentIndex++;
question.id = currentIndex; // 将当前序号赋值给题目的序号
// 打开choice_questions.txt文件
FILE *choiceFile = fopen("choice_questions.txt", "a");
if (choiceFile == NULL) {
printf("打开choice_questions.txt文件失败\n");
return;
}
// 将新的题目写入choice_questions.txt文件
fprintf(choiceFile, "\n%d %s", question.id, question.question);
fprintf(choiceFile, " %s", question.optionA);
fprintf(choiceFile, " %s", question.optionB);
fprintf(choiceFile, " %s", question.optionC);
fprintf(choiceFile, " %s", question.optionD);
fprintf(choiceFile, " %c", question.answer);
// 关闭choice_questions.txt文件
fclose(choiceFile);
// 创建新的选择题结点
ChoiceNode *newNode = malloc(sizeof(ChoiceNode));
newNode->data = question;
newNode->next = NULL;
// 将新结点插入链表末尾
if (list->tail == NULL) {
list->head = list->tail = newNode;
} else {
list->tail->next = newNode;
list->tail = newNode;
}
// 更新链表大小
list->size++;
}
void addFillQuestion(FillList *list, FillQuestion question) {
// 声明并初始化当前序号
int currentIndex = 1;
// 寻找下一个可用的序号
while (findFillNode(list, currentIndex) != NULL) {
currentIndex++;
}
question.id = currentIndex; // 将当前序号赋值给题目的序号
// 打开fill_questions.txt文件
FILE *file = fopen("fill_questions.txt", "a");
if (file == NULL) {
printf("文件打开失败\n");
return;
}
// 将新题目写入文件
fprintf(file, "%d %s %s\n", question.id, question.question, question.answer);
// 关闭文件
fclose(file);
// 创建新的填空题结点
FillNode *newNode = malloc(sizeof(FillNode));
newNode->data = question;
newNode->next = NULL;
// 将新结点插入链表末尾
if (list->tail == NULL) {
list->head = list->tail = newNode;
} else {
list->tail->next = newNode;
list->tail = newNode;
}
// 更新链表大小
list->size++;
}
void deleteChoiceQuestion(ChoiceList *list, int id) {
ChoiceNode *prev = NULL;
ChoiceNode *curr = list->head;
// 遍历链表,找到要删除的选择题结点
while (curr != NULL && curr->data.id != id) {
prev = curr;
curr = curr->next;
}
// 如果找到了要删除的结点
if (curr != NULL) {
// 如果要删除的结点是第一个结点
if (prev == NULL) {
list->head = curr->next;
} else {
prev->next = curr->next;
}
// 如果要删除的结点是最后一个结点
if (curr->next == NULL) {
list->tail = prev;
}
free(curr);
list->size--;
printf("删除成功\n");
} else {
printf("删除失败,没有找到题目编号为 %d 的选择题\n", id);
}
}
void deleteFillQuestion(FillList *list, int id) {
FillNode *prev = NULL;
FillNode *curr = list->head;
// 遍历链表,找到要删除的填空题结点
while (curr != NULL && curr->data.id != id) {
prev = curr;
curr = curr->next;
}
// 如果找到了要删除的填空题结点
if (curr != NULL) {
// 如果要删除的是链表的第一个结点
if (prev == NULL) {
list->head = curr->next;
} else {
prev->next = curr->next;
}
// 如果要删除的是链表的最后一个结点
if (curr == list->tail) {
list->tail = prev;
}
list->size--;
free(curr);
printf("填空题删除成功\n");
} else {
printf("填空题删除失败\n");
}
}
void backupQuestions(ChoiceList *choiceList, FillList *fillList) {
// 备份选择题
FILE *choiceFp = fopen("choice_questions_backup.txt", "w");
if (choiceFp == NULL) {
printf("打开选择题备份文件失败\n");
return;
}
ChoiceNode *curr = choiceList->head;
while (curr != NULL) {
fprintf(choiceFp, "%d %s %s %s %s %s %c\n",
curr->data.id, curr->data.question, curr->data.optionA, curr->data.optionB,
curr->data.optionC, curr->data.optionD, curr->data.answer);
curr = curr->next;
}
fclose(choiceFp);
// 备份填空题
FILE *fillFp = fopen("fill_questions_backup.txt", "w");
if (fillFp == NULL) {
printf("打开填空题备份文件失败\n");
return;
}
FillNode *curr2 = fillList->head;
while (curr2 != NULL) {
fprintf(fillFp, "%d %s %s\n", curr2->data.id, curr2->data.question, curr2->data.answer);
curr2 = curr2->next;
}
fclose(fillFp);
}
void deleteAllQuestions(ChoiceList *choiceList, FillList *fillList) {
// 删除选择题链表中的所有结点
ChoiceNode *curr = choiceList->head;
while (curr != NULL) {
ChoiceNode *temp = curr;
curr = curr->next;
free(temp);
}
choiceList->head = choiceList->tail = NULL;
choiceList->size = 0;
// 删除填空题链表中的所有结点
FillNode *curr2 = fillList->head;
while (curr2 != NULL) {
FillNode *temp = curr2;
curr2 = curr2->next;
free(temp);
}
fillList->head = fillList->tail = NULL;
fillList->size = 0;
}
void updateChoiceQuestion(ChoiceList *list, int id, char *question, char *optionA, char *optionB, char *optionC, char *optionD, char answer) {
// 找到要修改的选择题结点
ChoiceNode *node = findChoiceNode(list, id);
if (node == NULL) {
printf("未找到要修改的选择题\n");
return;
}
// 修改题目信息
if (strcmp(question, "-") != 0) {
strcpy(node->data.question, question);
}
if (strcmp(optionA, "-") != 0) {
strcpy(node->data.optionA, optionA);
}
if (strcmp(optionB, "-") != 0) {
strcpy(node->data.optionB, optionB);
}
if (strcmp(optionC, "-") != 0) {
strcpy(node->data.optionC, optionC);
}
if (strcmp(optionD, "-") != 0) {
strcpy(node->data.optionD, optionD);
}
if (answer != '-') {
node->data.answer = answer;
}
// 打开choice_questions.txt文件
FILE *file = fopen("choice_questions.txt", "w");
if (file == NULL) {
printf("文件打开失败\n");
return;
}
// 将所有选择题写入文件
ChoiceNode *curr = list->head;
while (curr != NULL) {
fprintf(file, "%d %s %s %s %s %s %c\n", curr->data.id, curr->data.question, curr->data.optionA,
curr->data.optionB, curr->data.optionC, curr->data.optionD, curr->data.answer);
curr = curr->next;
}
// 关闭文件
fclose(file);
}
void updateFillQuestion(FillList *list, int id, char *question, char *answer) {
FillNode *curr = list->head;
// 遍历链表,找到要修改的填空题结点
while (curr != NULL && curr->data.id != id) {
curr = curr->next;
}
// 如果没有找到,提示错误
if (curr == NULL) {
printf("没有找到编号为%d的填空题\n", id);
return;
}
// 更新题目
if (question != NULL) {
strcpy(curr->data.question, question);
}
// 更新答案
if (answer != NULL) {
strcpy(curr->data.answer, answer);
}
// 打开choice_questions.txt文件
FILE *file = fopen("choice_questions.txt", "w");
if (file == NULL) {
printf("文件打开失败\n");
return;
}
// 将所有填空题写入文件
while (curr != NULL) {
fprintf(file, "%d %s %s\n", curr->data.id, curr->data.question, curr->data.answer);
curr = curr->next;
}
// 关闭文件
fclose(file);
}
void queryChoiceQuestion(ChoiceList *list, int id) {
ChoiceNode *curr = list->head;
// 遍历链表,找到要查询的选择题结点
while (curr != NULL && curr->data.id != id) {
curr = curr->next;
}
// 如果没有找到,提示错误
if (curr == NULL) {
printf("没有找到编号为%d的选择题\n", id);
return;
}
// 打印题目内容
printf("编号: %d\n", curr->data.id);
printf("题目: %s\n", curr->data.question);
printf("选项A: %s\n", curr->data.optionA);
printf("选项B: %s\n", curr->data.optionB);
printf("选项C: %s\n", curr->data.optionC);
printf("选项D: %s\n", curr->data.optionD);
printf("正确答案: %c\n", curr->data.answer);
}
void queryFillQuestion(FillList *list, int id) {
FillNode *curr = list->head;
// 遍历链表,找到要查询的填空题结点
while (curr != NULL && curr->data.id != id) {
curr = curr->next;
}
// 如果没有找到,提示错误
if (curr == NULL) {
printf("没有找到编号为%d的填空题\n", id);
return;
}
// 打印题目内容
printf("编号: %d\n", curr->data.id);
printf("题目: %s\n", curr->data.question);
printf("答案: %s\n", curr->data.answer);
}
int countChoiceQuestions(ChoiceList *list) {
int count = 0;
ChoiceNode *curr = list->head;
while (curr != NULL) {
count++;
curr = curr->next;
}
return count;
}
int countFillQuestions(FillList *list) {
int count = 0;
FillNode *curr = list->head;
while (curr != NULL) {
count++;
curr = curr->next;
}
return count;
}
void printChoiceQuestion(const ChoiceQuestion *question) {
// 打印题目
printf("%d. %s\n", question->id, question->question);
// 打印选项
printf("A. %s\n", question->optionA);
printf("B. %s\n", question->optionB);
printf("C. %s\n", question->optionC);
printf("D. %s\n", question->optionD);
// 打印答案
printf("Answer: %c\n", question->answer);
}
void printFillQuestion(const FillQuestion *question) {
// 打印题目
printf("%d. %s\n", question->id, question->question);
// 打印答案
printf("Answer: %s\n", question->answer);
}
void queryQuestionsByContent(const ChoiceList *choiceList, const FillList *fillList, const char *content) {
// 遍历选择题链表,查找含有content的选择题
ChoiceNode *currChoice = choiceList->head;
while (currChoice != NULL) {
if (strstr(currChoice->data.question, content) != NULL ||
strstr(currChoice->data.optionA, content) != NULL ||
strstr(currChoice->data.optionB, content) != NULL ||
strstr(currChoice->data.optionC, content) != NULL ||
strstr(currChoice->data.optionD, content) != NULL) {
// 如果找到了,就打印这道题
printChoiceQuestion(&currChoice->data);
}
currChoice = currChoice->next;
}
// 遍历填空题链表,查找含有content的填空题
FillNode *currFill = fillList->head;
while (currFill != NULL) {
if (strstr(currFill->data.question, content) != NULL ||
strstr(currFill->data.answer, content) != NULL) {
// 如果找到了,就打印这道题
printFillQuestion(&currFill->data);
}
currFill = currFill->next;
}
}
void printMenu(){
printf("\n\n\n");
printf("\t\t\t====================================\n");
printf("\t\t\t| |\n");
printf("\t\t\t| 试 卷 系 统 |\n");
printf("\t\t\t| |\n");
printf("\t\t\t===================================\n");
printf("\t\t\t| |\n");
printf("\t\t\t| 1. 添加选择题 |\n");
printf("\t\t\t| 2. 删除选择题 |\n");
printf("\t\t\t| 3. 添加填空题 |\n");
printf("\t\t\t| 4. 删除填空题 |\n");
printf("\t\t\t| 5. 备份全部题目 |\n");
printf("\t\t\t| 6. 删除全部题目 |\n");
printf("\t\t\t| 7. 修改选择题 |\n");
printf("\t\t\t| 8. 修改填空题 |\n");
printf("\t\t\t| 9. 查询选择题 |\n");
printf("\t\t\t|10. 查询填空题 |\n");
printf("\t\t\t|11. 统计共有多少道题目 |\n");
printf("\t\t\t|12. 查询题目中含有特定内容的所有题目内容 |\n");
printf("\t\t\t|13.生成试卷 |\n");
printf("\t\t\t| 0.退出系统 |\n");
printf("\t\t\t====================================\n");
printf("\t\t\t请选择操作(输入0~13):");
}
int main() {
ChoiceList *choiceList = createChoiceList();
FillList *fillList = createFillList();
// 从文件中读取选择题和填空题
choiceList = readChoiceQuestionFile("choice_questions.txt", choiceList);
fillList = readFillQuestionFile("fill_questions.txt", fillList);
int choice;
int id;
int type;
int choiceNum;
int fillNum;
char content[100];
ChoiceQuestion choiceQuestion;
FillQuestion fillQuestion;
while (1) {
char question[100];
char optionA[100];
char optionB[100];
char optionC[100];
char optionD[100];
char answer[100];
char answerChoice;
// 打印菜单
printMenu();
printf("请输入您要进行的操作:");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("请输入要添加的选择题的题目内容:");
scanf("%s", choiceQuestion.question);
printf("请输入要添加的选择题的选项A:");
scanf("%s", choiceQuestion.optionA);
printf("请输入要添加的选择题的选项B:");
scanf("%s", choiceQuestion.optionB);
printf("请输入要添加的选择题的选项C:");
scanf("%s", choiceQuestion.optionC);
printf("请输入要添加的选择题的选项D:");
scanf("%s", choiceQuestion.optionD);
printf("请输入要添加的选择题的答案:");
scanf(" %c", &choiceQuestion.answer);
addChoiceQuestion(choiceList, choiceQuestion);
break;
case 2:
printf("请输入要删除的选择题的题目编号:");
scanf("%d", &id);
deleteChoiceQuestion(choiceList, id);
break;
case 3:
printf("请输入要添加的填空题的题目内容:");
scanf("%s", fillQuestion.question);
printf("请输入要添加的填空题的答案:");
scanf("%s", fillQuestion.answer);
addFillQuestion(fillList, fillQuestion);
break;
case 4:
printf("请输入要删除的填空题的题目编号:");
scanf("%d", &id);
deleteFillQuestion(fillList, id);
break;
case 5:
backupQuestions(choiceList, fillList);
break;
case 6:
deleteAllQuestions(choiceList, fillList);
break;
case 7:
printf("请输入要修改的选择题的题目编号:");
scanf("%d", &id);
printf("请输入要修改的选择题的题目内容(输入'-'表示不修改):");
scanf("%s", question);
printf("请输入要修改的选择题的选项A(输入'-'表示不修改):");
scanf("%s", optionA);
printf("请输入要修改的选择题的选项B(输入'-'表示不修改):");
scanf("%s", optionB);
printf("请输入要修改的选择题的选项C(输入'-'表示不修改):");
scanf("%s", optionC);
printf("请输入要修改的选择题的选项D(输入'-'表示不修改):");
scanf("%s", optionD);
printf("请输入要修改的选择题的正确答案(输入'-'表示不修改):");
scanf(" %c", &answerChoice);
updateChoiceQuestion(choiceList, id, question, optionA, optionB, optionC, optionD, answerChoice);
break;
case 8:
printf("请输入要修改的填空题的题目编号:");
scanf("%d", &id);
printf("请输入要修改的填空题的题目内容(输入'-'表示不修改):");
scanf("%s", question);
printf("请输入要修改的填空题的答案(输入'-'表示不修改):");
scanf("%s", answer);
updateFillQuestion(fillList, id, question, answer);
break;
case 9:
printf("请输入要查询的选择题的题目编号:");
scanf("%d", &id);
queryChoiceQuestion(choiceList, id);
break;
case 10:
printf("请输入要查询的填空题的题目编号:");
scanf("%d", &id);
queryFillQuestion(fillList, id);
break;
case 11:
printf("请输入要统计的题目的类型(0表示选择题,1表示填空题):");
scanf("%d", &type);
if (type == 0) {
printf("共有%d道选择题\n", countChoiceQuestions(choiceList));
} else if (type == 1) {
printf("共有%d道填空题\n", countFillQuestions(fillList));
} else {
printf("输入的类型错误\n");
}
break;
case 12:
printf("请输入要查询的题目中含有的特定内容:");
scanf("%s", content);
queryQuestionsByContent(choiceList, fillList, content);
break;
case 13:
printf("请输入选择题的数量:\n");
scanf("%d", &choiceNum);
printf("请输入填空题的数量:\n");
scanf("%d", &fillNum);
generateExam(choiceList, fillList, choiceNum, fillNum);
break;
case 0:
printf("退出系统\n");
exit(0);
break;
default:
printf("输入的操作编号有误\n");
break;
}
}
}
函数详解以及整体思路请看我的另一篇文章:
【C语言程序设计实验】试卷管理系统(完整代码+函数详解)
以上就是本次实验的内容,简单实现了一个试卷系统,内含一系列用于管理和生成试卷的功能,喜欢的话记得点赞关注加收藏,谢谢你的浏览。
实验文件直接点击此处领取。有帮助的话可以点赞收藏关注,谢谢。