【C语言程序设计实验】试卷管理系统(完整代码+函数详解) -->源代码文件文章末尾免费领取

目录

  • 实验简介
  • 一、实验要求
  • 二、实验代码
    • 1. 完整代码
    • 2. 代码解析
      • (1)get_next_question_number
      • (2)add_question
      • (3)delete_question
      • (4)backup_questions
      • (5)delete_all_questions
      • (6)modify_question
      • (7)search_question
      • (8)count_questions
      • (9)search_specific_content
      • (10)get_question_count
      • (11)get_random_number
      • (12)is_question_selected
      • (13)generate_exam_paper
      • (14)main
  • 三、效果展示
    • 1. 文档展示
      • (1)选择题文档 choice_question.txt
      • (2)填空题文档 fill_in_blank_questions.txt
      • (3)试卷文档 exam_paper.txt
    • 2. 菜单展示
  • 总结
  • 实验文件领取


实验简介

       老师在教学过程中,会经常以试卷的形式来检验学生的学习情况。现在由你来帮助老师设计一个试卷自动生成系统,完成从已有题库(题库包含2个文件,1个是选择题题库文件,1格式填空题题库文件)中随机提取指定题目书的题目生成一份新的试卷。该系统生成的试卷中只有2种题型:单项选择题、填空题(只有一个空)。


一、实验要求

       单项选择题包括题目编号、题目、选项A、选项B、选项C、选项D、答案
       填空题包括题目编号、题目、答案
功能:
       (1)试题添加:向试题库追加写入一道新的题目,要求题目编号自动生成,且与已存题目的编号不重复;所有内容不能为空。即不断充实题库;
       (2)试题删除:通过题目编号进行题目的删除,如果删除成功则提示删除成功,否则提示删除失败;
       (3)备份全部题目;
       (4)删除全部题目;
       (5)试题修改:通过题目编号查找对应题目,并修改指定的题目的内容,注意不是修改题目的全部内容,而是可以针对性的修改局部内容;
       (6)试题查询:通过题目编号查询指定的题目的所有内容;
       (7)统计共有多少道题目;
       (8)查询题目中含有某个特定内容(用户输入)的所有题目内容;
       (9)自动随机生成由单项选择题、填空题合在一起的试卷及标准答案2个文件(exam.txt和answer.txt),各题型的题目数由用户输入。注意选择题和填空题的题目数可以不一样;要求每次生成的试卷题目、顺序都不能完全相同。也就是要求真正的随机提取题目。
       (10)以上功能要求通过菜单的方式进行操作;要求对相应内容进行必要的合法性检查。要求具有良好的人机交互界面。每个题型要提前录入至少10道题。


二、实验代码

1. 完整代码

直接先给出实验完整代码:

#include 
#include 
#include 

#define CHOICE_QUESTION_FILE "choice_questions.txt"
#define FILL_IN_BLANK_QUESTION_FILE "fill_in_blank_questions.txt"

#define SINGLE_CHOICE_QUESTION 1
#define FILL_IN_THE_BLANK_QUESTION 2

#define MAX_QUESTION_LEN 256
#define MAX_FILENAME_LEN 256
#define MAX_OPTION_LEN 16
#define MAX_ANSWER_LEN 32

#define ADD_QUESTION 1
#define DELETE_QUESTION 2
#define BACKUP_QUESTIONS 3
#define DELETE_ALL_QUESTIONS 4
#define MODIFY_QUESTION 5
#define SEARCH_QUESTION 6
#define COUNT_QUESTIONS 7
#define SEARCH_SPECIFIC_CONTENT 8
#define GENERATE_EXAM_PAPER 9
#define EXIT 10


int get_next_question_number(const char *question_file, int question_type) {
    FILE *fp;
    int question_number;
    int choice_question_number;
    int fill_in_blank_question_number;
    char question[MAX_QUESTION_LEN];
    char option_a[MAX_OPTION_LEN];
    char option_b[MAX_OPTION_LEN];
    char option_c[MAX_OPTION_LEN];
    char option_d[MAX_OPTION_LEN];
    char answer[MAX_ANSWER_LEN];

    fp = fopen(question_file, "r");
    if (fp == NULL) {
        printf("无法打开文件\n");
        return -1;
    }

    if (question_type == 1) {
        choice_question_number = 1;
        while (fscanf(fp, "%d %s %s %s %s %s %s", &question_number, question, option_a, option_b, option_c, option_d,
                      answer) != EOF) {
            choice_question_number++;
        }
        fclose(fp);
        return choice_question_number;
    } else if (question_type == 2) {
        fill_in_blank_question_number = 1;
        while (fscanf(fp, "%d %s %s", &question_number, question, answer) != EOF) {
            fill_in_blank_question_number++;
        }
        fclose(fp);
        return fill_in_blank_question_number;
    } else {
        printf("无效问题类型\n");
        return -1;
    }
}

void add_question(const char *question_file, int question_type) {
    FILE *fp;
    int question_number;
    char question[MAX_QUESTION_LEN];
    char option_a[MAX_OPTION_LEN];
    char option_b[MAX_OPTION_LEN];
    char option_c[MAX_OPTION_LEN];
    char option_d[MAX_OPTION_LEN];
    char answer[MAX_ANSWER_LEN];

    fp = fopen(question_file, "a");
    if (fp == NULL) {
        printf("无法打开文件\n");
        return;
    }

    if (question_type == 1) {
        question_number = get_next_question_number(question_file, question_type);
        printf("输入题目:");
        scanf(" %s", question);
        printf("输入选项A: ");
        scanf(" %s", option_a);
        printf("输入选项B: ");
        scanf(" %s", option_b);
        printf("输入选项C: ");
        scanf(" %s", option_c);
        printf("输入选项D: ");
        scanf(" %s", option_d);
        printf("输入正确选项: ");
        scanf(" %s", answer);
        fprintf(fp, "%d %s %s %s %s %s %s\n",
                question_number, question, option_a, option_b, option_c, option_d, answer);
    } else if (question_type == 2) {
        question_number = get_next_question_number(question_file, question_type);
        printf("输入题目:");
        scanf(" %s", question);
        printf("输入答案:");
        scanf(" %s", answer);
        fprintf(fp, "%d %s %s\n", question_number, question, answer);
    } else {
        printf("无效问题类型\n");
    }

    fclose(fp);
}

void delete_question(const char *question_file, int question_number, int question_type) {
    FILE *fp;
    FILE *temp_fp;
    int curr_question_number;
    char question[MAX_QUESTION_LEN];
    char option_a[MAX_OPTION_LEN];
    char option_b[MAX_OPTION_LEN];
    char option_c[MAX_OPTION_LEN];
    char option_d[MAX_OPTION_LEN];
    char answer[MAX_ANSWER_LEN];

    fp = fopen(question_file, "r");
    if (fp == NULL) {
        printf("无法打开文件\n");
        return;
    }

    temp_fp = fopen("temp.txt", "w");
    if (temp_fp == NULL) {
        printf("无法打开文件\n");
        return;
    }

    if (question_type == 1) {
        while (fscanf(fp, "%d %s %s %s %s %s %s",
                      &curr_question_number, question, option_a, option_b, option_c, option_d, answer) != EOF) {
            if (curr_question_number != question_number) {
                fprintf(temp_fp, "%d %s %s %s %s %s %s\n",
                        curr_question_number, question, option_a, option_b, option_c, option_d, answer);
            }
        }
    } else if (question_type == 2) {
        while (fscanf(fp, "%d %s %s", &curr_question_number, question, answer) != EOF) {
            if (curr_question_number != question_number) {
                fprintf(temp_fp, "%d %s %s\n", curr_question_number, question, answer);
            }
        }
    } else {
        printf("无效问题类型\n");
    }

    fclose(fp);
    fclose(temp_fp);

    remove(question_file);
    rename("temp.txt", question_file);
}

void backup_questions(const char *question_file, int question_type) {
    FILE *fp;
    FILE *backup_fp;
    int question_number;
    char question[MAX_QUESTION_LEN];
    char option_a[MAX_OPTION_LEN];
    char option_b[MAX_OPTION_LEN];
    char option_c[MAX_OPTION_LEN];
    char option_d[MAX_OPTION_LEN];
    char answer[MAX_ANSWER_LEN];

    fp = fopen(question_file, "r");
    if (fp == NULL) {
        printf("无法打开文件\n");
        return;
    }

    backup_fp = fopen("question_backup.txt", "w");
    if (backup_fp == NULL) {
        printf("无法打开文件\n");
        return;
    }

    if (question_type == SINGLE_CHOICE_QUESTION) {
        while (fscanf(fp, "%d %s %s %s %s %s %s",
                      &question_number, question, option_a, option_b, option_c, option_d, answer) != EOF) {
            fprintf(backup_fp, "%d %s %s %s %s %s %s\n",
                    question_number, question, option_a, option_b, option_c, option_d, answer);
        }
    } else if (question_type == FILL_IN_THE_BLANK_QUESTION) {
        while (fscanf(fp, "%d %s %s", &question_number, question, answer) != EOF) {
            fprintf(backup_fp, "%d %s %s\n", question_number, question, answer);
        }
    }

    fclose(fp);
    fclose(backup_fp);
}

void delete_all_questions(const char *question_file, int question_type) {
    char backup_file[MAX_FILENAME_LEN];
    sprintf(backup_file, "%s_backup", question_file);

// 将所有题目备份到另一个文件
    backup_questions(question_file, question_type);

// 删除原文件
    remove(question_file);

// 创建空文件
    FILE *fp = fopen(question_file, "w");
    fclose(fp);
}

void modify_question(const char *question_file, int question_type, int question_number) {
// 打开题目文件
    FILE *fp = fopen(question_file, "r+");
    if (fp == NULL) {
        printf("无法打开文件 %s\n", question_file);
        return;
    }
    char line[MAX_QUESTION_LEN]; // 用来存储每行读入的内容
    int line_number = 0; // 用来记录当前行号
    int modified = 0; // 用来标记是否修改了题目

// 遍历每一行,找到需要修改的题目
    while (fgets(line, MAX_QUESTION_LEN, fp) != NULL) {
        // 如果找到了需要修改的题目,则修改题目内容
        if (line_number == question_number - 1) {
            // 将文件指针移动到当前行开头
            fseek(fp, -strlen(line), SEEK_CUR);

            // 读入修改后的题目内容
            if (question_type == SINGLE_CHOICE_QUESTION) {
                char question[MAX_QUESTION_LEN];
                while (strlen(question) == 0) {
                    printf("请输入修改后的题干:");
                    fgets(question, MAX_QUESTION_LEN, stdin);
                    question[strlen(question) - 1] = '\0'; // 去掉回车
                }
                printf("请输入修改后的选项A:");
                char option_a[MAX_OPTION_LEN];
                fgets(option_a, MAX_OPTION_LEN, stdin);
                option_a[strlen(option_a) - 1] = '\0'; // 去掉回车

                printf("请输入修改后的选项B:");
                char option_b[MAX_OPTION_LEN];
                fgets(option_b, MAX_OPTION_LEN, stdin);
                option_b[strlen(option_b) - 1] = '\0'; // 去掉回车

                printf("请输入修改后的选项C:");
                char option_c[MAX_OPTION_LEN];
                fgets(option_c, MAX_OPTION_LEN, stdin);
                option_c[strlen(option_c) - 1] = '\0'; // 去掉回车

                printf("请输入修改后的选项D:");
                char option_d[MAX_OPTION_LEN];
                fgets(option_d, MAX_OPTION_LEN, stdin);
                option_d[strlen(option_d) - 1] = '\0'; // 去掉回车

                printf("请输入修改后的正确答案:");
                char answer[MAX_ANSWER_LEN];
                fgets(answer, MAX_ANSWER_LEN, stdin);
                answer[strlen(answer) - 1] = '\0';

                // 将修改后的题目内容写入文件
                fprintf(fp, " %s %s %s %s %s %s ", question, option_a, option_b, option_c, option_d, answer);
            } else {
// 如果是填空题,则只需要输入修改后的题干和答案
                printf("请输入修改后的题干:");
                char question[MAX_QUESTION_LEN];
                fgets(question, MAX_QUESTION_LEN, stdin);
                question[strlen(question) - 1] = '\0'; // 去掉回车

                printf("请输入修改后的答案:");
                char answer[MAX_QUESTION_LEN];
                fgets(answer, MAX_QUESTION_LEN, stdin);
                answer[strlen(answer) - 1] = '\0'; // 去掉回车

// 将文件指针移动到当前行开头
                fseek(fp, -strlen(line), SEEK_CUR);

// 将修改后的题目内容写入文件
                fprintf(fp, " %s %s ", question_number, question, answer);
            }
// 标记已经修改了题目,退出循环
            modified = 1;
            break;
        }
        line_number++;
    }

// 如果未找到需要修改的题目,则输出提示信息
    if (!modified) {
        printf("未找到需要修改的题目\n");
    }

// 关闭文件
    fclose(fp);
}

void search_question(const char *question_file, int question_type, int question_number) {
    FILE *fp;
    int found = 0;
    int tmp_question_number;
    char question[MAX_QUESTION_LEN];
    char option_a[MAX_OPTION_LEN];
    char option_b[MAX_OPTION_LEN];
    char option_c[MAX_OPTION_LEN];
    char option_d[MAX_OPTION_LEN];
    char answer[MAX_ANSWER_LEN];

    if (question_type == SINGLE_CHOICE_QUESTION) {
        fp = fopen(question_file, "r");
        if (fp == NULL) {
            printf("无法打开文件\n");
            return;
        }
        // 查找指定题目
        while (fscanf(fp, "%d %s %s %s %s %s %s",
                      &tmp_question_number, question, option_a, option_b, option_c, option_d, answer) != EOF) {
            if (tmp_question_number == question_number) {
                found = 1;
                break;
            }
        }

// 如果找到了指定题目,输出题目信息
        if (found) {
            printf("题目编号:%d\n", question_number);
            printf("题目:%s\n", question);
            printf("选项 A:%s\n", option_a);
            printf("选项 B:%s\n", option_b);
            printf("选项 C:%s\n", option_c);
            printf("选项 D:%s\n", option_d);
            printf("答案:%s\n", answer);
        } else {
            printf("未找到指定题目\n");
        }
        fclose(fp);
    } else if (question_type == FILL_IN_THE_BLANK_QUESTION) {
        fp = fopen(question_file, "r");
        if (fp == NULL) {
            printf("无法打开文件\n");
            return;
        }
        // 查找指定题目
        while (fscanf(fp, "%d %s %s", &tmp_question_number, question, answer) != EOF) {
            if (tmp_question_number == question_number) {
                found = 1;
                break;
            }
        }

// 如果找到了指定题目,输出题目信息
        if (found) {
            printf("题目编号:%d\n", question_number);
            printf("题目:%s\n", question);
            printf("答案:%s\n", answer);
        } else {
            printf("未找到指定题目\n");
        }
        fclose(fp);
    } else {
        printf("无效题目类型\n");
    }
}

int count_questions(const char *question_file, int question_type) {
    FILE *fp;
    int count = 0;

    if (question_type == SINGLE_CHOICE_QUESTION) {
        fp = fopen(question_file, "r");
        if (fp == NULL) {
            printf("无法打开文件\n");
            return 0;
        }
        // 统计题目数量
        int question_number;
        char question[MAX_QUESTION_LEN];
        char option_a[MAX_OPTION_LEN];
        char option_b[MAX_OPTION_LEN];
        char option_c[MAX_OPTION_LEN];
        char option_d[MAX_OPTION_LEN];
        char answer[MAX_ANSWER_LEN];
        while (fscanf(fp, "%d %s %s %s %s %s %s",
                      &question_number, question, option_a, option_b, option_c, option_d, answer) != EOF) {
            count++;
        }

        fclose(fp);
    } else if (question_type == FILL_IN_THE_BLANK_QUESTION) {
        fp = fopen(question_file, "r");
        if (fp == NULL) {
            printf("无法打开文件\n");
            return 0;
        }
        // 统计题目数量
        int question_number;
        char question[MAX_QUESTION_LEN];
        char answer[MAX_ANSWER_LEN];
        while (fscanf(fp, "%d %s %s", &question_number, question, answer) != EOF) {
            count++;
        }

        fclose(fp);
    } else {
        printf("无效题目类型\n");
    }

    return count;
}

void search_specific_content(const char *question_file, int question_type, const char *specific_content) {
    FILE *fp;

    if (question_type == SINGLE_CHOICE_QUESTION) {
        fp = fopen(question_file, "r");
        if (fp == NULL) {
            printf("无法打开文件\n");
            return;
        }
        // 查找指定题目
        int question_number;
        char question[MAX_QUESTION_LEN];
        char option_a[MAX_OPTION_LEN];
        char option_b[MAX_OPTION_LEN];
        char option_c[MAX_OPTION_LEN];
        char option_d[MAX_OPTION_LEN];
        char answer[MAX_ANSWER_LEN];
        while (fscanf(fp, "%d %s %s %s %s %s %s", &question_number, question, option_a, option_b, option_c, option_d,
                      answer) != EOF) {
            if (strstr(question, specific_content) != NULL || strstr(option_a, specific_content) != NULL ||
                strstr(option_b, specific_content) != NULL || strstr(option_c, specific_content) != NULL ||
                strstr(option_d, specific_content) != NULL || strstr(answer, specific_content) != NULL) {
                printf("题目编号:%d\n", question_number);
                printf("题目:%s\n", question);
                printf("选项A:%s\n", option_a);
                printf("选项B:%s\n", option_b);
                printf("选项C:%s\n", option_c);
                printf("选项D:%s\n", option_d);
                printf("答案:%s\n", answer);
            }
        }

        fclose(fp);
    } else if (question_type == FILL_IN_THE_BLANK_QUESTION) {
        fp = fopen(question_file, "r");
        if (fp == NULL) {
            printf("无法打开文件\n");
            return;
        }
        // 查找指定题目
        int question_number;
        char question[MAX_QUESTION_LEN];
        char answer[MAX_ANSWER_LEN];
        while (fscanf(fp, "%d %s %s", &question_number, question, answer) != EOF) {
            if (strstr(question, specific_content) != NULL || strstr(answer,
                                                                     specific_content) != NULL) {
                printf("题目编号:%d\n", question_number);
                printf("题目:%s\n", question);
                printf("答案:%s\n", answer);
            }
        }

        fclose(fp);
    }
}

int get_question_count(const char *question_file, int question_type) {
    int count = 0;
    FILE *fp = fopen(question_file, "r");
    if (fp == NULL) {
        printf("无法打开文件\n");
        return 0;
    }
    if (question_type == SINGLE_CHOICE_QUESTION) {
        int curr_question_number;
        char question[MAX_QUESTION_LEN];
        char option_a[MAX_OPTION_LEN];
        char option_b[MAX_OPTION_LEN];
        char option_c[MAX_OPTION_LEN];
        char option_d[MAX_OPTION_LEN];
        char answer[MAX_ANSWER_LEN];
        while (fscanf(fp, "%d %s %s %s %s %s %s", &curr_question_number, question,
                      option_a, option_b, option_c, option_d, answer) != EOF) {
            count++;
        }
    } else if (question_type == FILL_IN_THE_BLANK_QUESTION) {
        int curr_question_number;
        char question[MAX_QUESTION_LEN];
        char answer[MAX_ANSWER_LEN];
        while (fscanf(fp, "%d %s %s", &curr_question_number, question, answer) != EOF) {
            count++;
        }
    } else {
        printf("无效问题类型\n");
    }

    fclose(fp);
    return count;
}

int get_random_number(int min, int max) {
    return rand() % (max - min + 1) + min;
}

int number = 1;

int is_question_selected(int question_number, int *question_numbers) {
    int i;
    for (i = 0; i < MAX_QUESTION_LEN; i++) {
        if (question_numbers[i] == question_number) {
            return 1;
        }
    }
    return 0;
}

void generate_exam_paper(const char *choice_question_file,
                         const char *fill_in_blank_question_file,
                         int num_choice_questions,
                         int num_fill_in_blank_questions) {
// 打开题目文件
    FILE *choice_fp = fopen(choice_question_file, "r");
    if (choice_fp == NULL) {
        printf("无法打开选择题文件\n");
        return;
    }
    FILE *fill_in_blank_fp = fopen(fill_in_blank_question_file, "r");
    if (fill_in_blank_fp == NULL) {
        printf("无法打开填空题文件\n");
        return;
    }
// 打开考试试卷文件
    FILE *exam_paper_fp = fopen("exam_paper.txt", "w");
    if (exam_paper_fp == NULL) {
        printf("无法打开试卷文件\n");
        return;
    }
// 随机生成num_choice_questions道单项选择题
    int choice_question_count = get_question_count(choice_question_file, SINGLE_CHOICE_QUESTION);
    if (num_choice_questions > choice_question_count) {
        printf("选择题数量大于最大的选择题数量 %d,应该小于等于最大的选择题数量\n", choice_question_count);
        return;
    }
    int choice_question_numbers[MAX_QUESTION_LEN] = {0};
    int choice_question_number;
    int count = 0; // 已经抽取到的题目数量
    fprintf(exam_paper_fp, "选择题:\n");
    while (count < num_choice_questions) {
        choice_question_number = get_random_number(1, choice_question_count);
        if (choice_question_numbers[choice_question_number - 1] == 0) {
            choice_question_numbers[choice_question_number - 1] = 1;
            //print_question(exam_paper_fp, choice_fp, choice_question_number, SINGLE_CHOICE_QUESTION);
            fseek(choice_fp, 0, SEEK_SET);
            int curr_choice_question_number;
            char question[MAX_QUESTION_LEN];
            char option_a[MAX_OPTION_LEN];
            char option_b[MAX_OPTION_LEN];
            char option_c[MAX_OPTION_LEN];
            char option_d[MAX_OPTION_LEN];
            char answer[MAX_ANSWER_LEN];
            while (fscanf(choice_fp, "%d %s %s %s %s %s %s", &curr_choice_question_number, question,
                          option_a, option_b, option_c, option_d, answer) != EOF) {
                if (curr_choice_question_number == choice_question_number) {
// 找到了指定的题目,把它打印到考卷文件里
                    fprintf(exam_paper_fp, "%d.", number++);
                    fprintf(exam_paper_fp, "%s", question);
                    fprintf(exam_paper_fp, " A.%s", option_a);
                    fprintf(exam_paper_fp, " B.%s", option_b);
                    fprintf(exam_paper_fp, " C.%s", option_c);
                    fprintf(exam_paper_fp, " D.%s\n", option_d);
                    break;
                }
            }
            count++;
        }
    }
    fprintf(exam_paper_fp, "\n");
// 随机生成num_fill_in_blank_questions道填空题
    int fill_in_blank_question_count = get_question_count(fill_in_blank_question_file, FILL_IN_THE_BLANK_QUESTION);
    if (num_fill_in_blank_questions > fill_in_blank_question_count) {
        printf("填空题数量大于最大的填空题数量 %d,应该小于等于最大的填空题数量\n", fill_in_blank_question_count);
        return;
    }
    int fill_in_blank_question_numbers[MAX_QUESTION_LEN] = {0};
    int fill_in_blank_question_number;
    count = 0;
    fprintf(exam_paper_fp, "填空题:\n");
    while (count < num_fill_in_blank_questions) {
        fill_in_blank_question_number = get_random_number(1, fill_in_blank_question_count);
        if (!is_question_selected(fill_in_blank_question_number, fill_in_blank_question_numbers)) {
            //print_question(exam_paper_fp, fill_in_blank_fp, fill_in_blank_question_number, FILL_IN_THE_BLANK_QUESTION);
            int curr_fill_in_blank_question_number;
            char question[MAX_QUESTION_LEN];
            char answer[MAX_ANSWER_LEN];
            while (fscanf(fill_in_blank_fp, "%d %s %s", &curr_fill_in_blank_question_number, question, answer) != EOF) {
                if (curr_fill_in_blank_question_number == fill_in_blank_question_number) {
                    fseek(fill_in_blank_fp, 0, SEEK_SET);
                    fprintf(exam_paper_fp, "%d. %s\n", number++, question);
                    break;
                }
            }
            fill_in_blank_question_numbers[count] = fill_in_blank_question_number;
            count++;
        }
    }

// 关闭文件
    fclose(choice_fp);
    fclose(fill_in_blank_fp);
    fclose(exam_paper_fp);
}

int main() {
    int choice;
    int question_number;
    char content[MAX_QUESTION_LEN];
    int num_choice_questions;
    int num_fill_in_blank_questions;

    while (1) {
        printf("\n菜单:\n");
        printf("1. 添加题目\n");
        printf("2. 删除题目\n");
        printf("3. 备份全部题目\n");
        printf("4. 删除全部题目\n");
        printf("5. 修改题目\n");
        printf("6. 题目查询\n");
        printf("7. 统计题目个数\n");
        printf("8. 查询题目中含有某个特定内容的所有题目内容\n");
        printf("9. 生成试卷\n");
        printf("10. 退出\n");
        printf("输入数字选择对应操作: ");
        scanf("%d", &choice);
        if (choice == EXIT) {
            break;
        }

        switch (choice) {
            case ADD_QUESTION:
                printf("输入题目类型 (1 选择题, 2 填空题): ");
                scanf("%d", &question_number);
                if (question_number == 1) {
                    add_question(CHOICE_QUESTION_FILE, question_number);
                } else if (question_number == 2) {
                    add_question(FILL_IN_BLANK_QUESTION_FILE, question_number);
                } else {
                    printf("无效的题目类型\n");
                }
                break;
            case DELETE_QUESTION:
                printf("输入题目类型 (1 选择题, 2 填空题): ");
                scanf("%d", &question_number);
                if (question_number == 1) {
                    printf("输入题号: ");
                    scanf("%d", &question_number);
                    delete_question(CHOICE_QUESTION_FILE, question_number, question_number);
                } else if (question_number == 2) {
                    printf("输入题号: ");
                    scanf("%d", &question_number);
                    delete_question(FILL_IN_BLANK_QUESTION_FILE, question_number, question_number);
                } else {
                    printf("无效的题目类型\n");
                }
                break;
            case BACKUP_QUESTIONS:
                printf("输入题目类型 (1 选择题, 2 填空题): ");
                scanf("%d", &question_number);
                if (question_number == 1) {
                    backup_questions(CHOICE_QUESTION_FILE, question_number);
                } else if (question_number == 2) {
                    backup_questions(FILL_IN_BLANK_QUESTION_FILE, question_number);
                } else {
                    printf("无效的题目类型\n");
                }
                break;
            case DELETE_ALL_QUESTIONS:
                printf("输入题目类型 (1 选择题, 2 填空题): ");
                scanf("%d", &question_number);
                if (question_number == 1) {
                    delete_all_questions(CHOICE_QUESTION_FILE, question_number);
                } else if (question_number == 2) {
                    delete_all_questions(FILL_IN_BLANK_QUESTION_FILE, question_number);
                } else {
                    printf("无效的题目类型\n");
                }
                break;
            case MODIFY_QUESTION:
                printf("输入题目类型 (1 选择题, 2 填空题): ");
                scanf("%d", &question_number);
                if (question_number == 1) {
                    printf("输入题号: ");
                    scanf("%d", &question_number);
                    modify_question(CHOICE_QUESTION_FILE, SINGLE_CHOICE_QUESTION, question_number);
                } else if (question_number == 2) {
                    printf("输入题号: ");
                    scanf("%d", &question_number);
                    modify_question(FILL_IN_BLANK_QUESTION_FILE, FILL_IN_THE_BLANK_QUESTION, question_number);
                } else {
                    printf("无效的数据类型\n");
                }
                break;
            case SEARCH_QUESTION:
                printf("输入题目类型 (1 选择题, 2 填空题): ");
                scanf("%d", &question_number);
                if (question_number == 1) {
                    printf("输入题号: ");
                    scanf("%d", &question_number);
                    search_question(CHOICE_QUESTION_FILE, SINGLE_CHOICE_QUESTION, question_number);
                } else if (question_number == 2) {
                    printf("输入题号: ");
                    scanf("%d", &question_number);
                    search_question(FILL_IN_BLANK_QUESTION_FILE, FILL_IN_THE_BLANK_QUESTION, question_number);
                } else {
                    printf("无效的数据类型\n");
                }
                break;
            case COUNT_QUESTIONS:
                printf("输入题目类型 (1 选择题, 2 填空题): ");
                scanf("%d", &question_number);
                if (question_number == 1) {
                    printf("选择题的数量为: %d\n", count_questions(CHOICE_QUESTION_FILE, question_number));
                } else if (question_number == 2) {
                    printf("填空题的数量为: %d\n", count_questions(FILL_IN_BLANK_QUESTION_FILE, question_number));
                } else {
                    printf("无效的数据类型\n");
                }
                break;
            case SEARCH_SPECIFIC_CONTENT:
                printf("输入题目类型 (1 选择题, 2 填空题): ");
                scanf("%d", &question_number);
                printf("输入内容: ");
                scanf("%s", content);
                if (question_number == 1) {
                    search_specific_content(CHOICE_QUESTION_FILE, question_number, content);
                } else if (question_number == 2) {
                    search_specific_content(FILL_IN_BLANK_QUESTION_FILE, question_number, content);
                } else {
                    printf("无效的数据类型\n");
                }
                break;
            case GENERATE_EXAM_PAPER:
                number = 1;
                printf("输入选择题的数量: ");
                scanf("%d", &num_choice_questions);
                printf("输入填空题的数量: ");
                scanf("%d", &num_fill_in_blank_questions);
                generate_exam_paper(CHOICE_QUESTION_FILE,
                                    FILL_IN_BLANK_QUESTION_FILE,
                                    num_choice_questions,
                                    num_fill_in_blank_questions);
                break;
            default:
                printf("无效的选择\n");
                break;
        }
    }
    return 0;
}

2. 代码解析

(1)get_next_question_number

       get_next_question_number函数是用来获取下一个题目编号的函数。它接收一个参数,即题目所在的文件名,然后从文件中读取最后一条记录,并从中获取题目编号。然后,它将题目编号加1并返回,以便用于新题目的编号。例如,如果当前题库文件已有5道选择题,那么执行get_next_question_number(“questions.txt”, SINGLE_CHOICE_QUESTION)将会返回6。

(2)add_question

       add_question函数是一个用来添加题目的函数。它需要两个参数:question_file和question_type。question_file是一个字符串,表示题目文件的路径;question_type是一个整数,表示题目类型。
       在这个函数中,会根据question_type的值,询问用户输入不同类型的题目信息。如果question_type为SINGLE_CHOICE_QUESTION,则询问用户输入单选题的信息(包括题干、选项、正确答案等);如果question_type为FILL_IN_THE_BLANK_QUESTION,则询问用户输入填空题的信息(包括题干和答案等)。
       在用户输入了题目信息后,函数会将这些信息写入question_file指定的文件中,完成添加题目的操作。

(3)delete_question

       delete_question函数是用来删除给定的题目文件中的某一题的函数。在执行时,函数首先会打开给定的题目文件,然后读入每一行的内容,并判断当前行是否是要删除的题目。如果找到了要删除的题目,函数就会将文件指针移动到该行的开头,然后删除该行。函数最后会关闭打开的文件。

(4)backup_questions

       backup_questions函数用于备份题目文件。它打开指定的题目文件并从中读取题目内容,然后打开一个名为"question_backup.txt"的新文件并将读取到的题目内容写入该文件中。它支持两种题目类型,即选择题和填空题。对于选择题,函数会读取题号、题干、4个选项和正确答案,并将这些信息写入备份文件中。对于填空题,函数会读取题号、题干和答案,并将这些信息写入备份文件中。函数在读取完所有题目后关闭输入文件和输出文件。

(5)delete_all_questions

       delete_all_questions函数的功能是删除所有的题目。首先,它会将所有的题目备份到另一个文件。然后,它会删除原来的文件。最后,它会创建一个空的文件,以便之后可以继续添加新的题目。

(6)modify_question

       modify_question是用来修改已有题目的函数。在调用这个函数时,需要传入三个参数:题目文件名、题目类型(选择题或填空题)、题目编号。函数会先打开题目文件,然后读入每一行的内容,找到需要修改的题目,然后要求用户输入修改后的题目内容,并将修改后的题目内容写入文件。如果没有找到需要修改的题目,则提示未找到。最后,关闭文件并退出函数。

(7)search_question

       search_question函数用于在指定的试题文件中搜索指定的试题编号的试题。如果找到了该试题,则将该试题的信息打印出来,否则显示找不到该试题的信息。该函数需要三个参数:question_file表示试题文件的文件名,question_type表示试题类型(选择题或填空题),question_number表示试题编号。

(8)count_questions

       count_questions函数是用来计算题库中题目的数量的。它接受两个参数:question_file是题库的文件名,question_type是题目的类型(比如选择题、填空题等)。这个函数会打开题库文件,遍历文件中的每一行,并计算题目的数量。最后,它返回题目的数量。

(9)search_specific_content

       search_specific_content函数的功能是在给定的题目文件中搜索指定的内容,并将找到的所有题目的信息输出到屏幕上。题目文件参数表示要搜索的文件名,question_type参数表示题目的类型(选择题或填空题),specific_content参数表示要搜索的关键字。如果找不到任何匹配的题目,则函数会输出提示信息。

(10)get_question_count

       get_question_count的功能是统计给定文件中指定类型的题目数量。其中,question_file是指定的文件名,question_type是题目类型,该函数会返回文件中指定类型的题目数量。

(11)get_random_number

       get_random_number函数是用来生成一个在指定范围内的随机数的函数。它接受两个参数,min和max,表示随机数的范围。函数会返回一个在这个范围内的整数。

(12)is_question_selected

       is_question_selected函数用来检查一道题是否已经被选择过。它接受两个参数:一个是要检查的题目编号,另一个是一个整数数组,存储了所有已经被选择的题目编号。如果给定的题目编号在数组中出现过,则函数返回1,否则返回0。
       例如,假设有一个数组question_numbers存储了已经被选择的题目编号,则调用is_question_selected(3, question_numbers)可以用来检查题目编号为3的题目是否已经被选择过。如果3在question_numbers数组中出现过,则函数返回1,否则返回0。

(13)generate_exam_paper

       generate_exam_paper函数的功能是在指定的文件中选择指定数量的选择题和填空题,并生成一张考试试卷。它会读取指定的文件中的题目,随机选择num_choice_questions道选择题和num_fill_in_blank_questions道填空题,并将这些题目打印到输出流中。

(14)main

       main函数包含一个无限循环,用于显示菜单并执行用户选择的操作。用户可以选择添加题目、删除题目、备份全部题目、删除全部题目、修改题目、查询题目、统计题目个数、查询含有某个特定内容的所有题目或生成试卷,并实现对应的功能。


三、效果展示

1. 文档展示

(1)选择题文档 choice_question.txt

       choice_question为选择题题库文档,内容示例:

【C语言程序设计实验】试卷管理系统(完整代码+函数详解) -->源代码文件文章末尾免费领取_第1张图片
       选择题文档第一列为题目序号,第二列为题目题干,第三列为选项A内容,第四列为选项B内容,第五列为选项C内容,第六列为选项D内容,第七列为答案。

(2)填空题文档 fill_in_blank_questions.txt

fill_in_blank_questions.txt为填空题文档,内容示例:
【C语言程序设计实验】试卷管理系统(完整代码+函数详解) -->源代码文件文章末尾免费领取_第2张图片
填空题文档第一列为题目序号,第二列为题目题干,第三列为题目答案。

(3)试卷文档 exam_paper.txt

exam_paper.txt为生成随机试卷文档,生成示例:

【C语言程序设计实验】试卷管理系统(完整代码+函数详解) -->源代码文件文章末尾免费领取_第3张图片

2. 菜单展示

【C语言程序设计实验】试卷管理系统(完整代码+函数详解) -->源代码文件文章末尾免费领取_第4张图片
具体的功能可以自行运行尝试,这里我就不一一示范了。

总结

以上就是本次实验的内容,本文简单实现了一个试卷系统,内含一系列用于管理和生成试卷的功能,喜欢的话记得点赞关注加收藏,谢谢你的浏览。


实验文件领取

实验文件直接点击此处领取。有帮助的话可以点赞收藏关注,谢谢。

你可能感兴趣的:(c语言,开发语言)