C语言学生管理系统如何实现核心功能?

99ANYc3cd6
预计阅读时长 30 分钟
位置: 首页 C语言 正文
  1. 添加学生信息 (学号、姓名、成绩)
  2. 显示所有学生信息
  3. 根据学号查找学生
  4. 根据学号删除学生
  5. 根据成绩对学生进行排序
  6. 将学生信息保存到文件
  7. 从文件加载学生信息

程序的整体结构

为了使代码清晰、易于维护和扩展,我们将采用模块化的设计思想:

c语言程序设计学生管理系统
(图片来源网络,侵删)
  • student.h (头文件): 定义学生结构体、函数原型以及常量。
  • `student.c (源文件): 实现所有在头文件中声明的函数。
  • `main.c (主程序): 包含main函数,负责显示菜单和调用其他函数。

student.h - 头文件

这个文件定义了程序的核心数据结构和所有函数的声明。

#ifndef STUDENT_H
#define STUDENT_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义一个常量,表示最多能存储的学生数量
#define MAX_STUDENTS 100
// 定义学生结构体
typedef struct {
    int id;         // 学号
    char name[50];  // 姓名
    float score;    // 成绩
} Student;
// 全局变量,用于存储学生数组和当前学生数量
Student students[MAX_STUDENTS];
int student_count = 0;
// 函数原型声明
void display_menu();
void add_student();
void display_all_students();
void find_student_by_id();
void delete_student_by_id();
void sort_students_by_score();
void save_to_file();
void load_from_file();
#endif // STUDENT_H

student.c - 功能实现文件

这个文件包含了所有具体功能的实现逻辑。

#include "student.h"
// 显示主菜单
void display_menu() {
    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("  0. 退出系统\n");
    printf("=====================================\n");
    printf("请输入您的选择: ");
}
// 添加学生信息
void add_student() {
    if (student_count >= MAX_STUDENTS) {
        printf("错误:学生数量已达到上限,无法添加!\n");
        return;
    }
    Student new_student;
    printf("请输入学号: ");
    scanf("%d", &new_student.id);
    getchar(); // 消耗掉输入缓冲区中的换行符
    // 检查学号是否已存在
    for (int i = 0; i < student_count; i++) {
        if (students[i].id == new_student.id) {
            printf("错误:学号 %d 已存在,添加失败!\n", new_student.id);
            return;
        }
    }
    printf("请输入姓名: ");
    fgets(new_student.name, sizeof(new_student.name), stdin);
    new_student.name[strcspn(new_student.name, "\n")] = 0; // 移除fgets读取的换行符
    printf("请输入成绩: ");
    scanf("%f", &new_student.score);
    students[student_count++] = new_student;
    printf("学生信息添加成功!\n");
}
// 显示所有学生信息
void display_all_students() {
    if (student_count == 0) {
        printf("当前没有学生信息!\n");
        return;
    }
    printf("\n%-10s %-20s %-10s\n", "学号", "姓名", "成绩");
    printf("----------------------------------------\n");
    for (int i = 0; i < student_count; i++) {
        printf("%-10d %-20s %-10.2f\n", students[i].id, students[i].name, students[i].score);
    }
}
// 根据学号查找学生
void find_student_by_id() {
    int id, found = 0;
    printf("请输入要查找的学号: ");
    scanf("%d", &id);
    for (int i = 0; i < student_count; i++) {
        if (students[i].id == id) {
            printf("\n找到学生信息:\n");
            printf("学号: %d, 姓名: %s, 成绩: %.2f\n", students[i].id, students[i].name, students[i].score);
            found = 1;
            break;
        }
    }
    if (!found) {
        printf("未找到学号为 %d 的学生!\n", id);
    }
}
// 根据学号删除学生
void delete_student_by_id() {
    int id, found = 0;
    printf("请输入要删除的学号: ");
    scanf("%d", &id);
    for (int i = 0; i < student_count; i++) {
        if (students[i].id == id) {
            found = 1;
            // 将后面的所有学生信息前移一位
            for (int j = i; j < student_count - 1; j++) {
                students[j] = students[j + 1];
            }
            student_count--; // 学生总数减一
            printf("学号为 %d 的学生信息已删除!\n", id);
            break;
        }
    }
    if (!found) {
        printf("未找到学号为 %d 的学生,删除失败!\n", id);
    }
}
// 使用冒泡排序根据成绩对学生进行排序(降序)
void sort_students_by_score() {
    if (student_count < 2) {
        printf("学生数量不足,无需排序!\n");
        return;
    }
    for (int i = 0; i < student_count - 1; i++) {
        for (int j = 0; j < student_count - 1 - i; j++) {
            if (students[j].score < students[j + 1].score) {
                // 交换两个学生的信息
                Student temp = students[j];
                students[j] = students[j + 1];
                students[j + 1] = temp;
            }
        }
    }
    printf("学生信息已按成绩降序排序!\n");
}
// 将学生信息保存到文件
void save_to_file() {
    char filename[100];
    printf("请输入要保存的文件名 ( students.dat): ");
    scanf("%s", filename);
    FILE *fp = fopen(filename, "wb"); // "wb" 表示以二进制写入模式打开
    if (fp == NULL) {
        printf("无法打开文件 %s 进行写入!\n", filename);
        return;
    }
    // 先写入学生数量
    fwrite(&student_count, sizeof(int), 1, fp);
    // 再写入所有学生数据
    fwrite(students, sizeof(Student), student_count, fp);
    fclose(fp);
    printf("成功将 %d 条学生信息保存到文件 %s!\n", student_count, filename);
}
// 从文件加载学生信息
void load_from_file() {
    char filename[100];
    printf("请输入要加载的文件名: ");
    scanf("%s", filename);
    FILE *fp = fopen(filename, "rb"); // "rb" 表示以二进制读取模式打开
    if (fp == NULL) {
        printf("无法打开文件 %s 进行读取!\n", filename);
        return;
    }
    // 先读取学生数量
    fread(&student_count, sizeof(int), 1, fp);
    // 检查是否超出最大容量
    if (student_count > MAX_STUDENTS) {
        printf("文件中的学生数量超过系统上限,只加载前 %d 条,\n", MAX_STUDENTS);
        student_count = MAX_STUDENTS;
    }
    // 读取所有学生数据
    fread(students, sizeof(Student), student_count, fp);
    fclose(fp);
    printf("成功从文件 %s 加载了 %d 条学生信息!\n", filename, student_count);
}

main.c - 主程序入口

这个文件负责程序的流程控制,通过循环和switch语句来响应用户的选择。

#include "student.h"
int main() {
    int choice;
    // 程序启动时尝试从默认文件加载
    // load_from_file(); // 如果希望启动时自动加载,可以取消这行注释
    while (1) {
        display_menu();
        scanf("%d", &choice);
        switch (choice) {
            case 1:
                add_student();
                break;
            case 2:
                display_all_students();
                break;
            case 3:
                find_student_by_id();
                break;
            case 4:
                delete_student_by_id();
                break;
            case 5:
                sort_students_by_score();
                break;
            case 6:
                save_to_file();
                break;
            case 7:
                load_from_file();
                break;
            case 0:
                printf("感谢使用,再见!\n");
                exit(0); // 退出程序
            default:
                printf("无效的输入,请重新选择!\n");
        }
    }
    return 0;
}

如何编译和运行

  1. 保存文件: 将上面的三段代码分别保存为 student.hstudent.cmain.c,并将它们放在同一个文件夹下。

    c语言程序设计学生管理系统
    (图片来源网络,侵删)
  2. 编译: 打开终端(或命令提示符),进入该文件夹,使用GCC编译器进行编译,你需要将 .c 文件编译并链接成一个可执行文件。

    # -o student_system 指定输出的可执行文件名为 student_system
    # main.c 是主程序
    # student.c 是功能实现
    # student.h 会被 main.c 和 student.c 自动包含
    gcc main.c student.c -o student_system
  3. 运行: 编译成功后,在终端中运行生成的可执行文件。

    • Windows 上:
      student_system.exe
    • LinuxmacOS 上:
      ./student_system

程序演示流程

  1. 程序启动,显示菜单。
  2. 选择 1,添加几个学生(101, "张三", 85.5; 102, "李四", 92.0; 103, "王五", 78.5)。
  3. 选择 2,查看所有学生信息,确认添加成功。
  4. 选择 5,按成绩排序。
  5. 再次选择 2,可以看到学生列表已按成绩从高到低排列。
  6. 选择 3,输入学号 102,查找李四的信息。
  7. 选择 6,将信息保存到文件(students.dat)。
  8. 选择 0,退出程序。
  9. 重新运行程序,选择 7,从刚才保存的 students.dat 文件加载数据。
  10. 选择 2,可以看到之前保存的学生信息又回来了。

可以进一步改进的地方

这个程序已经具备了基本功能,但作为课程设计,你还可以考虑以下扩展:

  • 数据持久化: 目前数据是保存在内存中的,退出程序就丢失了,虽然我们实现了文件读写,但可以让程序在启动时自动加载一个默认文件(如 students.dat),在退出时自动保存,提升用户体验。
  • 输入验证: 对用户输入进行更严格的校验,
    • 成绩必须在0-100之间。
    • 学号必须是正整数。
    • 姓名不能为空。
  • 更丰富的排序: 增加按学号排序、按姓名排序等功能。
  • 修改学生信息: 增加一个功能,允许用户根据学号修改某个学生的信息。
  • 动态内存分配: 使用 mallocrealloc 来动态分配内存,而不是使用固定大小的数组,这样可以处理任意数量的学生(仅受系统内存限制)。
  • 更友好的用户界面: 使用更清晰的格式或简单的清屏函数(如 system("cls")system("clear"))来美化界面。

希望这个详细的实现能帮助你完成你的C语言课程设计!

c语言程序设计学生管理系统
(图片来源网络,侵删)
-- 展开阅读全文 --
头像
C语言课程设计成绩管理系统如何实现?
« 上一篇 03-03
织梦会员每日下载次数上限是多少?
下一篇 » 03-03

相关文章

取消
微信二维码
支付宝二维码

目录[+]