学生基本信息管理C语言如何实现?

99ANYc3cd6
预计阅读时长 34 分钟
位置: 首页 C语言 正文
  1. 结构体:用于定义学生信息的结构。
  2. 文件操作:将学生数据持久化存储到文件中,程序关闭后数据不丢失。
  3. 核心功能
    • 添加学生信息
    • 显示所有学生信息
    • 根据学号查找学生
    • 根据学号删除学生
    • 根据学号修改学生信息
  4. 用户界面:通过一个简单的菜单让用户选择操作。

程序设计思路

  1. 数据结构:使用 struct 定义一个 Student 结构体,包含学号、姓名、年龄、性别和成绩等字段。
  2. 数据存储:使用二进制文件("students.dat")来存储学生数据,二进制文件读写效率高,且结构体可以直接写入和读出,非常方便。
  3. 功能模块化:将每个功能(如添加、显示、查找等)都写成独立的 C 函数,使代码结构清晰,易于维护。
  4. 主循环:在 main 函数中使用一个 while 循环来显示菜单,并根据用户的选择调用相应的功能函数,直到用户选择退出。

完整 C 语言代码

下面是完整的、可运行的 C 语言代码,你可以直接复制到一个 .c 文件(student_management.c)中进行编译和运行。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h> // 用于 getch() 函数,实现“按任意键继续”
// 定义学生结构体
struct Student {
    char id[20];      // 学号
    char name[50];    // 姓名
    int age;          // 年龄
    char gender[10];  // 性别
    float score;      // 成绩
};
// 函数声明
void addStudent();
void displayStudents();
void searchStudent();
void deleteStudent();
void modifyStudent();
void saveToFile(struct Student students[], int count);
int loadFromFile(struct Student students[]);
// 全局变量,用于存储学生数组和学生数量
#define MAX_STUDENTS 100
struct Student students[MAX_STUDENTS];
int student_count = 0;
// 主函数
int main() {
    // 程序启动时,先从文件加载数据
    student_count = loadFromFile(students);
    int choice;
    while (1) {
        // 清屏,创建一个清爽的界面
        system("cls"); // Windows系统使用 "cls",Linux/macOS使用 "clear"
        printf("\n-----------------------------\n");
        printf("  学生信息管理系统 (C语言版)\n");
        printf("-----------------------------\n");
        printf("  1. 添加学生信息\n");
        printf("  2. 显示所有学生\n");
        printf("  3. 查找学生信息\n");
        printf("  4. 删除学生信息\n");
        printf("  5. 修改学生信息\n");
        printf("  0. 退出系统\n");
        printf("-----------------------------\n");
        printf("  请输入您的选择: ");
        scanf("%d", &choice);
        // 处理用户输入
        switch (choice) {
            case 1:
                addStudent();
                break;
            case 2:
                displayStudents();
                break;
            case 3:
                searchStudent();
                break;
            case 4:
                deleteStudent();
                break;
            case 5:
                modifyStudent();
                break;
            case 0:
                printf("感谢使用,再见!\n");
                // 退出前保存数据
                saveToFile(students, student_count);
                exit(0); // 正常退出程序
            default:
                printf("无效的输入,请重新选择!\n");
                break;
        }
        // 暂停,让用户看清结果
        printf("\n按任意键返回主菜单...");
        getch(); // 等待用户按下任意键
    }
    return 0;
}
// 1. 添加学生信息
void addStudent() {
    if (student_count >= MAX_STUDENTS) {
        printf("学生数量已达上限,无法添加!\n");
        return;
    }
    struct Student s;
    printf("请输入学号: ");
    scanf("%s", s.id);
    // 检查学号是否已存在
    for (int i = 0; i < student_count; i++) {
        if (strcmp(students[i].id, s.id) == 0) {
            printf("错误:该学号已存在!\n");
            return;
        }
    }
    printf("请输入姓名: ");
    scanf("%s", s.name);
    printf("请输入年龄: ");
    scanf("%d", &s.age);
    printf("请输入性别: ");
    scanf("%s", s.gender);
    printf("请输入成绩: ");
    scanf("%f", &s.score);
    students[student_count++] = s;
    printf("学生信息添加成功!\n");
}
// 2. 显示所有学生信息
void displayStudents() {
    if (student_count == 0) {
        printf("当前没有任何学生信息!\n");
        return;
    }
    printf("\n%-15s %-20s %-10s %-10s %-10s\n", "学号", "姓名", "年龄", "性别", "成绩");
    printf("------------------------------------------------\n");
    for (int i = 0; i < student_count; i++) {
        printf("%-15s %-20s %-10d %-10s %-10.2f\n", 
               students[i].id, 
               students[i].name, 
               students[i].age, 
               students[i].gender, 
               students[i].score);
    }
}
// 3. 根据学号查找学生
void searchStudent() {
    if (student_count == 0) {
        printf("当前没有任何学生信息!\n");
        return;
    }
    char id[20];
    printf("请输入要查找的学生学号: ");
    scanf("%s", id);
    for (int i = 0; i < student_count; i++) {
        if (strcmp(students[i].id, id) == 0) {
            printf("\n找到学生信息:\n");
            printf("学号: %s\n", students[i].id);
            printf("姓名: %s\n", students[i].name);
            printf("年龄: %d\n", students[i].age);
            printf("性别: %s\n", students[i].gender);
            printf("成绩: %.2f\n", students[i].score);
            return; // 找到后直接返回
        }
    }
    printf("未找到学号为 %s 的学生!\n", id);
}
// 4. 根据学号删除学生
void deleteStudent() {
    if (student_count == 0) {
        printf("当前没有任何学生信息!\n");
        return;
    }
    char id[20];
    printf("请输入要删除的学生学号: ");
    scanf("%s", id);
    for (int i = 0; i < student_count; i++) {
        if (strcmp(students[i].id, id) == 0) {
            // 将后面的所有学生信息前移一位,覆盖掉要删除的学生
            for (int j = i; j < student_count - 1; j++) {
                students[j] = students[j + 1];
            }
            student_count--; // 学生总数减一
            printf("学号为 %s 的学生信息已删除!\n", id);
            return;
        }
    }
    printf("未找到学号为 %s 的学生,删除失败!\n", id);
}
// 5. 根据学号修改学生信息
void modifyStudent() {
    if (student_count == 0) {
        printf("当前没有任何学生信息!\n");
        return;
    }
    char id[20];
    printf("请输入要修改的学生学号: ");
    scanf("%s", id);
    for (int i = 0; i < student_count; i++) {
        if (strcmp(students[i].id, id) == 0) {
            printf("找到学生 %s,请输入新的信息:\n", students[i].name);
            printf("请输入新姓名 (原: %s): ", students[i].name);
            scanf("%s", students[i].name);
            printf("请输入新年龄 (原: %d): ", students[i].age);
            scanf("%d", &students[i].age);
            printf("请输入新性别 (原: %s): ", students[i].gender);
            scanf("%s", students[i].gender);
            printf("请输入新成绩 (原: %.2f): ", students[i].score);
            scanf("%f", &students[i].score);
            printf("学生信息修改成功!\n");
            return;
        }
    }
    printf("未找到学号为 %s 的学生,修改失败!\n", id);
}
// 将数据保存到文件
void saveToFile(struct Student students[], int count) {
    FILE *fp = fopen("students.dat", "wb"); // "wb" 表示以二进制写入模式打开文件
    if (fp == NULL) {
        printf("无法打开文件进行保存!\n");
        return;
    }
    // 一次写入整个结构体数组
    fwrite(students, sizeof(struct Student), count, fp);
    fclose(fp);
    printf("数据已成功保存到文件 students.dat,\n");
}
// 从文件加载数据
int loadFromFile(struct Student students[]) {
    FILE *fp = fopen("students.dat", "rb"); // "rb" 表示以二进制读取模式打开文件
    if (fp == NULL) {
        // 如果文件不存在,则返回0,表示没有数据
        return 0;
    }
    // 一次读取整个结构体数组
    int count = fread(students, sizeof(struct Student), MAX_STUDENTS, fp);
    fclose(fp);
    printf("数据已从文件 students.dat 加载,共 %d 条记录,\n", count);
    return count;
}

如何编译和运行

  1. 保存代码:将上面的代码保存为 student_management.c
  2. 编译
    • 如果你使用的是 GCC 编译器(在 Linux, macOS 或 Windows 的 MinGW/Cygwin 中),打开终端或命令提示符,进入文件所在目录,然后运行:
      gcc student_management.c -o student_management
    • 如果你使用的是 Visual Studio,创建一个新的 C++ 控制台项目,并将代码粘贴到 .c 文件中,然后生成解决方案。
  3. 运行
    • 在 GCC 环境下,运行生成的可执行文件:
      ./student_management
    • 在 Windows (GCC) 环境下:
      student_management.exe
    • 在 Visual Studio 中,按 F5 或点击“开始调试”按钮。

代码讲解

  • struct Student:这是核心数据结构,定义了每个学生包含哪些信息。
  • main() 函数:程序入口,它首先调用 loadFromFile 从文件加载数据,然后进入一个无限循环来显示菜单和处理用户输入。system("cls") 用于清屏,getch() 用于实现“按任意键继续”的交互。
  • addStudent():提示用户输入学生信息,并检查学号是否重复,如果一切正常,则将新学生添加到 students 数组的末尾,并增加 student_count
  • displayStudents():遍历 students 数组,使用 printf 的格式化输出功能,以表格形式展示所有学生信息。
  • searchStudent():遍历数组,通过 strcmp 函数比较学号,找到后打印该学生的详细信息。
  • deleteStudent():遍历数组找到目标学生,然后使用一个 for 循环将目标学生之后的所有元素向前移动一位,从而覆盖掉要删除的学生,最后将 student_count 减一。
  • modifyStudent():找到目标学生后,允许用户重新输入该学生的各项信息,直接覆盖数组中原有的数据。
  • saveToFile()loadFromFile()
    • fopen("students.dat", "wb"):以二进制写入模式打开文件,如果文件不存在,会创建一个新文件。
    • fwrite(students, sizeof(struct Student), count, fp):这是关键,它将 students 数组中 countstruct Student 大小的数据块一次性写入文件,效率很高。
    • fopen("students.dat", "rb"):以二进制读取模式打开文件。
    • fread(students, sizeof(struct Student), MAX_STUDENTS, fp):一次性从文件中读取最多 MAX_STUDENTS 个学生结构体到 students 数组中。
    • 使用 fclose(fp) 关闭文件是一个好习惯,可以释放资源。

可能的改进方向

这个版本已经是一个功能完整的管理系统,但如果你想进一步学习和改进,可以考虑以下几点:

  1. 动态内存分配:目前使用固定大小的数组 (MAX_STUDENTS),限制了学生数量,可以使用 mallocreallocfree 来动态分配内存,实现无限添加学生。
  2. 排序功能:增加一个“按成绩排序”或“按学号排序”的功能,可以使用 qsort 函数(C标准库中的快速排序函数)来实现。
  3. 更健壮的输入验证:检查年龄是否为正数,成绩是否在0-100之间等,防止用户输入无效数据。
  4. 更友好的界面:使用颜色或更复杂的布局来美化控制台界面。
  5. 数据加密:如果对安全性要求高,可以在写入文件前对数据进行简单的加密,读出时再解密。
  6. 多文件组织:将函数声明放在 .h 头文件中,函数实现在 .c 源文件中,使项目结构更规范。
-- 展开阅读全文 --
头像
C语言程序设计基础该怎么学?
« 上一篇 今天
C语言如何生成不重复的随机数?
下一篇 » 今天

相关文章

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

目录[+]