02学生管理系统(队列)

预处理

#pragma warning(disable : 4996)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define STUDENT_NAME_SEX_MAX 20
#define STUDENT_SEX_MAX 5
#define STUDENT_INFORTMATION 20
#define SUBJECT_NUMBER 2
#define LEN sizeof(struct student)
#define PRINT_STUDENT_INFO(student) \
    printf(" %d\t %s\t %s\t %s\t %.2f\t %.2f\t %.2f\t %.2f\n", \
    (student).num, (student).name, (student).clas, (student).sex, \
    (student).Eng_score, (student).C_score, (student).total, (student).aver)
//printf("学号: %d\t姓名: %s\t班级: %s\t性别: %s\t英语成绩: %.2f\tC语言成绩: %.2f\t总成绩: %.2f\t平均成绩: %.2f\n", 
int functionCalled = 0;//读取文件一次标记

菜单

// 显示菜单函数
void menu() {
    printf("\n\n\n");
    printf("\t\t-------------------------------------------------\n");
    printf("\t\t||              ----------------               ||\n");
    printf("\t\t||**************学生信息管理系统(队列版)*******||\n");
    printf("\t\t||              ----------------               ||\n");
    printf("\t\t||                                             ||\n");
    printf("\t\t||~~~~~~~~~~~~~~~1.录入学生信息~~~~~~~~~~~~~~~~||\n");
    printf("\t\t||~~~~~~~~~~~~~~~2.删除学生信息~~~~~~~~~~~~~~~~||\n");
    printf("\t\t||~~~~~~~~~~~~~~~3.修改学生信息~~~~~~~~~~~~~~~~||\n");
    printf("\t\t||~~~~~~~~~~~~~~~4.查询学生信息~~~~~~~~~~~~~~~~||\n");
    printf("\t\t||~~~~~~~~~~~~~~~5.显示学生信息~~~~~~~~~~~~~~~~||\n");
    printf("\t\t||~~~~~~~~~~~~~~~6.排序学生信息~~~~~~~~~~~~~~~~||\n");
    printf("\t\t||~~~~~~~~~~~~~~~7.显示最好成绩~~~~~~~~~~~~~~~~||\n");
    printf("\t\t||~~~~~~~~~~~~~~~8.分组统计成绩~~~~~~~~~~~~~~~~||\n");
    printf("\t\t||~~~~~~~~~~~~~~~9.清屏~~~~~~~~~~~~~~~~~~~~~~~~||\n");
    printf("\t\t||                                             ||\n");
    printf("\t\t||*********************************************||\n");
}

结构体

typedef struct student {
    int num;
    char name[STUDENT_NAME_SEX_MAX];
    char clas[STUDENT_NAME_SEX_MAX];
    char sex[STUDENT_SEX_MAX];
    float Eng_score;
    float C_score;
    float total;
    float aver;
} Student;

typedef struct {
    Student queue[STUDENT_INFORTMATION];// 存储学生信息的数组
    int front, rear;
} StudentQueue;

主函数

int main() {
    StudentQueue queue = { {0} };
    Student stu;
    memset(&stu, 0, sizeof(stu));
    initQueue(&queue);
    int countptr = 0;
    int* count = &countptr; // 记录读取的学生数量

    menu(); // 显示菜单
    int choice = 0;
    printf("请选择功能(1-9):\n");
    int num;
    float n;
    scanf("%d", &choice);
    while (choice){
        if (choice >= 1 && choice <= 9) {
            switch (choice) {
            case 1: inStudent(&queue,count); 
                    // 将队列中的所有学生信息写入文件
                    writeQueueToFile(&queue, "stu.txt");
                break;
            case 2:
                printf("请输入要删除的学生学号:");
                scanf("%d", &num);
                deleteStudent(&queue,count, num);
                break;
            case 3:
                printf("请输入要修改的学生学号:");
                scanf("%d", &num);
                updateStudent(&queue,count, num);
                break;
            case 4:
                printf("请输入要查询的学生学号:");
                scanf("%d", &num);
                selectStudent(&queue,count, num);
                break;
            case 5: printStudents(&queue,count); break;
            case 6: sortStudents(&queue,count); break;
            case 7: maxStudent(&queue,count); break;
            case 8:
                printf("请输入按总成绩分组的值:");
                scanf("%f", &n);
                cutStudents(&queue,count, n);
                break;
            case 9: clearScreen(); break;
            default: printf("无效的选项,请重新选择。\n");
            }
            if (choice == 9)menu();
            printf("\n");
            printf("请选择功能(1-9):");
            scanf("%d", &choice);
        }
    }

    return 0;
}

队列操作函数(初始化,判断,入出队,队首)

// 队列初始化
void initQueue(StudentQueue* q) {
    if (q == NULL) return; // 检查指针是否为 NULL
    q->front = -1; // 假设 -1 表示队列为空
    q->rear = -1;
}

// 判断队列是否为空
int isEmpty(StudentQueue* q) {
    if (q == NULL) return -1; // 检查指针是否为 NULL
    return q->front == -1;

}

// 判断队列是否为满
int isFull(StudentQueue* q) {
    // 队列满的条件是 rear 指针等于队列的最大容量减1
    return q->rear == STUDENT_INFORTMATION - 1;
}

// 入队操作
void enqueue(StudentQueue* q, Student student) {
    if (isFull(q)) { // 检查队列是否已满
        printf("Queue is full\n");
        return;
    }
    // 确保 rear 指针在有效范围内
    if (q->rear==-1&&q->front==-1) {
        q->rear = 0;
        q->front = 0;
        q->queue[q->rear] = student; // 将 student 赋值给队尾元素
        q->rear++; // 更新 rear 指针
    }
    else if(q->rear>0&&q->rear<STUDENT_INFORTMATION-1){
        q->queue[q->rear] = student; // 将 student 赋值给队尾元素
        q->rear++; // 更新 rear 指针

    }else {
        // 处理无法入队的异常情况
        printf("Failed to enqueue student due to index out of bounds.\n");
    }
}

// 出队操作,并打印
void dequeue(StudentQueue* q) {
    if (isEmpty(q)) {
        printf("Queue is empty\n");
        return ;
    }
    // 打印队列头部元素
    PRINT_STUDENT_INFO(q->queue[q->front]);
    q->front = (q->front + 1); 
}

// 查看队首元素
Student peek(StudentQueue* q) {
    if (!isEmpty(q))
        return q->queue[q->front];
    Student temp = { 0 };
    return temp;
}

其他函数原型声明

void printAndDequeue(StudentQueue* q);//打印队列
void readStudentsFromFile(StudentQueue* q, int* count, const char* filename);//从文件读取放入队列
void writeQueueToFile(StudentQueue* q, const char* filename);//从队列写入文件
void clearQueueContent(StudentQueue* q);// 清空队列内容实现
void menu(void);//菜单
void inStudent(StudentQueue* q, int* count);//录入
void deleteStudent(StudentQueue* q, int* count, int num);//删除
void updateStudent(StudentQueue* q, int* count, int num);//修改
void selectStudent(StudentQueue* q, int* count, int num);//查询
void printStudents(StudentQueue* q, int* count);//显示
void sortStudents(StudentQueue* q, int* count);
void maxStudent(StudentQueue* q, int* count);
void cutStudents(StudentQueue* q, int* count, float n);
void clearScreen(void);

录入

// 录入学生信息
void inStudent(StudentQueue* q, int* count) {
    //clearQueueContent(q);
    Student stu;
    memset(&stu, 0, sizeof(stu)); // 初始化 stu 为 0
    char ch[2];
    int i;
    if(!q)readStudentsFromFile(q, count, "stu.txt");
    printf("当前队列中已有 %d 条学生记录。\n", *count);
    printf("输入学生信息(y/n);\n");
    scanf("%s", ch);
    while (strcmp(ch, "y") == 0 || strcmp(ch, "Y") == 0) {
        // 清空缓冲区中的换行符
        while (getchar() != '\n');

        printf("学号: \n");
        scanf("%d", &stu.num);
        for (i = q->front; i != q->rear; ++i) {
            if (q->queue[i].num == stu.num) {
                printf("学号已存在,请重新输入。\n");
                return; // 函数退出,不再继续执行后面的代码
            }
        }

        printf("姓名: \n");
        scanf("%s", &stu.name);
        printf("班级: \n");
        scanf("%s", &stu.clas);
        printf("性别: \n");
        scanf("%s", &stu.sex);
        printf("英语成绩: \n");
        scanf("%f", &stu.Eng_score);
        printf("C语言成绩: \n");
        scanf("%f", &stu.C_score);
        stu.total = stu.Eng_score + stu.C_score;
        stu.aver = stu.total / SUBJECT_NUMBER;
        if (strcmp(ch, "y") == 0 || strcmp(ch, "Y") == 0)
        {
            enqueue(q, stu);
            (*count)++;
        }
        printf("是否继续录入学生信息(y/n):");
        scanf("%s", ch);
    }
    
}

删除

// 删除学生信息
void deleteStudent(StudentQueue* q,int* count, int num) {
    //clearQueueContent(q);
    /*if (!q)
        readStudentsFromFile(q, count, "stu.txt");*/
    if (*count == 0) {
        printf("文件无内容。\n");
        return;
    }
    Student tempStu[STUDENT_INFORTMATION];
    int tempIndex = 0;
    while (*count) {
        if (q->queue[*count].num != num) {
            tempStu[tempIndex++] = q->queue[*count];
        }
        else {
            printf("找到学生信息,正在删除...\n");
            printf("删除成功!\n");
        }
        (*count)--;
    }
    if(*count!=0)printf("无该学生信息\n");
    else {
        FILE* fp = fopen("stu.txt", "wb");
        // 重写更新后的学生信息到文件
        fseek(fp, 0, SEEK_SET); // 移动文件指针到文件开始处
        for (int i = 0; i < tempIndex; i++) {
            fwrite(&tempStu[i], LEN, 1, fp);
        }
        fclose(fp);
        // 重置队列
        initQueue(q);
        for (int i = 0; i < tempIndex; i++) {
            enqueue(q, tempStu[i]);
        }
    }
    //dequeue(q);
}


修改


// 修改学生信息
void updateStudent(StudentQueue* q,int*count, int num) {
    //clearQueueContent(q);
    /*if (!q)
        readStudentsFromFile(q, count, "stu.txt");*/
    Student stu;
    memset(&stu, 0, sizeof(stu)); 
    if (isEmpty(q)) {
        printf("队列为空。\n");
        return;
    }
    int found = 0;
    // 遍历队列寻找对应的学生信息
    for (int i = q->front; i != q->rear; i = (i + 1) % STUDENT_INFORTMATION) {
        if (q->queue[i].num == num) {
            found = 1;
            stu = q->queue[i];
            break;
        }
    }
    if (!found) {
        printf("未找到学号为 %d 的学生。\n", num);
        return;
    }
    // 打印可修改的字段
    printf("找到学生信息,请输入要修改的字段(0完成修改):\n");
    printf("1: 姓名 2: 班级 3: 性别 4: 英语成绩 5: C语言成绩\n");
    int option;
    scanf("%d", &option);
    while (option) {
        switch (option) {
        case 1: printf("姓名: "); scanf("%s", &stu.name); break;
        case 2: printf("班级: "); scanf("%s", &stu.clas); break;
        case 3: printf("性别: "); scanf("%s", &stu.sex); break;
        case 4: printf("英语成绩: "); scanf("%f", &stu.Eng_score); break;
        case 5: printf("C语言成绩: "); scanf("%f", &stu.C_score); break;
        default: printf("无效的选项。\n"); return;
        }
        // 重新计算总分和平均分
        stu.total = stu.Eng_score + stu.C_score;
        stu.aver = stu.total / SUBJECT_NUMBER;
        printf("修改后的信息:\n");
        PRINT_STUDENT_INFO(stu);
        printf("继续修改其他字段吗(0完成修改)?:");
        scanf("%d", &option);
    }
    // 将更新后的学生信息重新入队
    for (int i = q->front; i != q->rear; i = (i + 1) % STUDENT_INFORTMATION) {
        if (q->queue[i].num == num) {
            q->queue[i] = stu;
            break;
        }
    }
    printf("学生信息已更新。\n");
}

查询

// 查询学生信息
void selectStudent(StudentQueue* q,int* count, int num) {
    //clearQueueContent(q);
    /*if (!q)
        readStudentsFromFile(q, count, "stu.txt");*/
    if (isEmpty(q)) {
        printf("队列为空。\n");
        return;
    }
    int found = 0;
    for (int i = q->front; i != q->rear; i = (i + 1) % STUDENT_INFORTMATION) {
        if (q->queue[i].num == num) {
            found = 1;
            printf("找到学生信息:\n");
            PRINT_STUDENT_INFO(q->queue[i]);
            break;
        }
    }
    if (!found) {
        printf("未找到学号为 %d 的学生。\n", num);
    }
    //dequeue(q);
}

显示

// 显示所有学生信息
void printStudents(StudentQueue* q,int* count) {

    // 从文件读取学生信息并加入队列
    /*if(!q)
       readStudentsFromFile(q,count, "stu.txt");*/
    if (isEmpty(q)) {
        printf("队列无内容。\n");
        return;
    }
    printf("学号\t姓名\t班级\t性别\t英语成绩\tC语言成绩\t总成绩\t平均成绩\n");
    printAndDequeue(q);
    
}

排序

// 排序学生信息(以学号为例)
void sortStudents(StudentQueue* q,int* count) {
        readStudentsFromFile(q, count, "stu.txt");
    int i, j;
    Student temp;
    if (isEmpty(q)) {
        printf("队列为空。\n");
        return;
    }
    // 冒泡排序
    for (i = 0; i < STUDENT_INFORTMATION - 1; i++) {
        for (j = 0; j < STUDENT_INFORTMATION - i - 1; j++) {
            if (q->queue[j].num > q->queue[j + 1].num) {
                temp = q->queue[j];
                q->queue[j] = q->queue[j + 1];
                q->queue[j + 1] = temp;
            }
        }
    }
    printf("排序完成。\n");
    printAndDequeue(q);
}

最好成绩

// 显示最好成绩
void maxStudent(StudentQueue* q,int* count) {
    //clearQueueContent(q);
    /*if (!q)
        readStudentsFromFile(q, count, "stu.txt");*/
    if (isEmpty(q)) {
        printf("队列为空。\n");
        return;
    }
    Student maxStu = q->queue[q->front];
    for (int i = q->front; i != q->rear; i = (i + 1) % STUDENT_INFORTMATION) {
        if (q->queue[i].total > maxStu.total) {
            maxStu = q->queue[i];
        }
    }
    printf("总成绩最高的学生信息:\n");
    PRINT_STUDENT_INFO(maxStu);
    //dequeue(q);
}

分组统计

// 分组统计学生成绩
void cutStudents(StudentQueue* q,int* count, float n)
{
    //clearQueueContent(q);
    /*if (!q)
        readStudentsFromFile(q, count, "stu.txt");*/
    int above = 0, below = 0;
    if (isEmpty(q)) {
        printf("队列为空。\n");
        return;
    }
    printf("总成绩大于%.2f的学生:\n", n);
    for (int i = q->front; i != q->rear; i = (i + 1) % STUDENT_INFORTMATION) {
        if (q->queue[i].total > n) {
            PRINT_STUDENT_INFO(q->queue[i]);
            above++;
        }
    }
    printf("总成绩小于%.2f的学生:\n", n);
    for (int i = q->front; i != q->rear; i = (i + 1) % STUDENT_INFORTMATION) {
        if (q->queue[i].total < n) {
            PRINT_STUDENT_INFO(q->queue[i]);
            below++;
        }
    }
    printf("大于指定分数的学生有%d人,小于指定分数的学生有%d人。\n", above, below);
    //dequeue(q);
}

清屏

// 清屏
void clearScreen() {
    system("cls");
}

思考

加入操作,可不可以不重复读取文件数据入队列?
显示操作,从文件获取信息输出
不同模块的共用队列,队列初始化
break,continue,return   效果
队列缓冲区问题
结构体与队列数据处理问题
队列缓存乱加入文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值