基于C语言的简易学生管理系统设计

该代码可以完整运行,已包含全部代码!

1.序言:

这是博主第一次写博客记录自己的日常,分享给C语言的初学者但需要一个小项目练手。

项目名称:基于C语言的简易学生管理系统设计

功能:简易系统登录、显示操作菜单栏;学生信息录入、查找、修改、删除、展示;学生信息文件储存、加载;学生信息的统计、排序。

此为系统功能框架:

2.头文件和数据结构:

数据结构很简单,使用的是结构体。学生信息结构体包含学号id,姓名name,性别gender,分数score;学生列表结构体则包含学生结构体,当前人数count,容量capacity。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


// 定义学生结构体
typedef struct
{
    int id;          // 学号
    char name[50];   // 姓名
    char gender[10]; // 性别
    float score;     // 成绩
} Student;

//
// 定义学生列表结构体
typedef struct
{
    Student *students; // 指向学生数组的指针
    int count;         // 当前学生数量
    int capacity;      // 当前容量
} StudentList;

 3.学生信息录入功能实现

包含初始化学生列表、判断学号是否唯一(防止重复插入)、信息插入功能(该函数首先判断学生列表内容是否足够,不够则动态增加列表长度,然后依次输入信息、最后验证分数输入是否符合标准)。

// 初始化学生列表
void InitStudentList(StudentList *P, int capacity)
{
    P->students = (Student *)malloc(capacity * sizeof(Student));
    if (!P->students)
    {
        printf("学生列表初始化失败!");
        exit(EXIT_FAILURE);
    }
    else
    {
        P->count = 0;
        P->capacity = capacity;
    }
}

//
// 判定学号是否唯一
int IsidUnique(StudentList *P, int id)
{
    for (int i = 0; i < P->count; i++)
    {
        if (id == P->students[i].id) // 重复了
        {
            printf("该学生已存在系统内");
            return 0;
        }
    }
    return 1;
}

//
// 添加学生信息,带验证判断
void AddStudentList(StudentList *P)
{
    if (P->count >= P->capacity) // 表明默认的结构体长度不够,需要实时扩展内存
    {
        int Newcapacity = P->capacity * 2; // 翻倍扩容
        Student *NewStu = (Student *)realloc(P->students, sizeof(P->students) * Newcapacity);
        if (!NewStu) // 若内存扩展失败,则退出
        {
            printf("内存扩展失败!\n");
            exit(EXIT_FAILURE);
        }
        // 扩展成功,更新数据
        P->capacity = Newcapacity;
        P->students = NewStu;
    }

    Student *newstu = &P->students[P->count];

    printf("请输入学号: ");
    scanf("%d", &(newstu->id));
    while (!IsidUnique(P, newstu->id))
    {
        printf("学号已存在,请重新输入学号: ");
        scanf("%d", &(newstu->id));
    }

    printf("请输入姓名: ");
    scanf("%s", newstu->name);

    printf("请输入性别: ");
    scanf("%s", newstu->gender);

    printf("请输入成绩 (0-100): ");
    scanf("%f", &(newstu->score));

    // 验证成绩范围
    while (newstu->score < 0 || newstu->score > 100)
    {
        printf("成绩应在0到100之间, 请重新输入成绩: ");
        scanf("%f", &(newstu->score));
    }
    P->count++;
    printf("信息输入成功!");
}

4.显示当前所有学生的信息

原理很简单,输入当前列表,遍历即可。

// 显示学生的信息
void displayStudent(StudentList *P)
{
    if (P->count == 0)
    {
        printf("系统内无信息\n");
        return;
    }

    printf("\n当前学生信息:\n");
    printf("------------------------------------------------------------\n");
    printf("| 学号 |     姓名     |   性别   |   成绩   |\n");
    printf("------------------------------------------------------------\n");
    for (int i = 0; i < P->count; i++)
    {
        printf("| %-4d | %-8s | %-2s | %-4.2f |\n",
               P->students[i].id,
               P->students[i].name,
               P->students[i].gender,
               P->students[i].score);
    }
    printf("------------------------------------------------------------\n");
}

5.从文件加载学生的信息,保存学生信息至文件

//
// 释放内容
void freeStudent(StudentList *P)
{
    free(P->students);
    P->students = NULL;
    P->count = 0;
    P->capacity = 0;
}

//
// 保存学生信息到文件
void saveStudentsToFile(StudentList *list, const char *filename)
{
    FILE *file = fopen(filename, "wb");
    if (!file)
    {
        printf("无法打开文件进行保存。\n");
        return;
    }
    fwrite(list->students, sizeof(Student), list->count, file);
    fclose(file);
    printf("学生信息已保存到文件 %s\n", filename);
}

//
// 从文件加载学生信息
void loadStudentsFromFile(StudentList *list, const char *filename)
{
    FILE *file = fopen(filename, "rb");
    if (!file)
    {
        printf("无法打开文件进行加载。\n");
        return;
    }
    // 先清空现有数据
    // freeStudent(list);
    // 尝试加载
    size_t read = fread(list->students, sizeof(Student), list->capacity, file);
    if (read > 0)
    {
        list->count = (int)read;
    }
    else
    {
        list->count = 0;
    }
    fclose(file);
    printf("学生信息已从文件 %s 加载。\n", filename);
}

5.查找学生的信息

Search_stu函数提供了id和name两种方式查找学生的信息,由flag决定。遍历即可实现。

//
// 查找学生的信息,可使用id、name
int Search_stu(StudentList *P)
{
    int flag = 0;
    printf("使用学号id查询输入1, 使用姓名查询使用0: ");
    scanf("%d", &flag);

    if (flag) // 使用id经行查询
    {
        int new_id = 0;
        printf("请输入学号id: ");
        scanf("%d", &new_id);
        for (int i = 0; i < P->count; i++)
        {
            if (P->students[i].id == new_id)
            {
                printf("| %-4d | %-8s | %-2s | %-4.2f |\n",
                       P->students[i].id,
                       P->students[i].name,
                       P->students[i].gender,
                       P->students[i].score);
                return 0;
            }
        }
        printf("无该学生的信息!\n");
        return 0;
    }
    //
    // 使用姓名查询
    else
    {
        char new_name[20];
        printf("请输入姓名name: ");
        scanf("%s", &new_name);
        for (int i = 0; i < P->count; i++)
        {
            if (strcmp(P->students[i].name, new_name) == 0)
            {
                printf("| %-4d | %-8s | %-2s | %-4.2f |\n",
                       P->students[i].id,
                       P->students[i].name,
                       P->students[i].gender,
                       P->students[i].score);
                return 0;
            }
        }
        printf("无该学生的信息!\n");
        return 0;
    }
}

6.统计学生的信息

该模块只提供了显示最高、最低成绩,平均成绩。感兴趣的同学可自行添加功能。

//
int max(int a, int b)
{
    return (a > b) ? a : b;
}

//
int min(int a, int b)
{
    return (a > b) ? b : a;
}
//
// 学生统计模块
void Student_information_statistics(StudentList *P)
{
    if (P->count == 0)
    {
        printf("系统内无学生信息,无法统计");
        return;
    }
    // 统计学生信息相关的统计量
    float sum_score = 0, ave_score = 0, max_score = 0, min_score = 0;
    for (size_t i = 0; i < P->count; i++)
    {
        sum_score += P->students[i].score;
        max_score = max(P->students[i].score, max_score);
        min_score = min(P->students[i].score, max_score);
    }
    ave_score = sum_score / P->count;
    printf("学生的平均成绩:%-4.2f, 最高成绩: %4.2f, 最低成绩:%4.2f\n",
           ave_score, max_score, min_score);
}

7.修改学生的信息

提供了两种方式:按学号id、name两种方式查找到某位同学,在进行信息修改,通过赋值即可。

// 修改学生信息
void modify_stu_information(StudentList *P)
{
    if (P->count == 0)
    {
        printf("系统内无学生信息,无法修改");
        return;
    }

    int modify_id = 0;
    printf("请输入修改学生的学号id\n");
    scanf("%d", &modify_id);

    for (size_t i = 0; i < P->count; i++)
    {
        if (P->students[i].id == modify_id)
        {
            printf("要修改名字吗?[y/n]\n");
            char modify_name;
            scanf(" %c", &modify_name);
            if (modify_name == 'y' || modify_name == 'Y')
            {
                printf("请输入新的姓名: ");
                scanf("%s", &P->students[i].name);
                printf("姓名已修改为: %s\n", P->students[i].name);
            }

            //
            printf("要修改性别吗?[y/n]\n");
            char modify_gender;
            scanf(" %c", &modify_gender);
            if (modify_gender == 'y' || modify_gender == 'Y')
            {
                printf("请输入新的性别: ");
                scanf(" %s", &P->students[i].gender);
                printf("性别已修改为: %s\n", P->students[i].gender);
            }

            //
            printf("要修改分数吗?[y/n]\n");
            char modify_score;
            scanf(" %c", &modify_score);
            if (modify_score == 'y' || modify_score == 'Y')
            {
                printf("请输入新的分数: ");
                scanf("%f", &P->students[i].score);
                printf("分数已修改为: %.2f\n", P->students[i].score);
            }
            return;
        }
    }
    printf("未找到该学生!\n");
}

8.删除学生信息

/
// 删除学生信息
void delete_stu(StudentList *P)
{
    if (P->count == 0)
    {
        printf("系统内无任何学生信息,无法删除!");
        return;
    }

    printf("请输入想要删除的学生名字:");
    char del_name[10];
    scanf("%s", &del_name);
    for (size_t i = 0; i < P->count; i++)
    {
        // 先找到name,然后将后面的list一个一个向前移
        if (strcmp(del_name, P->students[i].name) == 0)
        {
            for (size_t j = i; j < P->count - 1; j++)
            {
                P->students[j] = P->students[j + 1];
            }

            P->count--;
            printf("学生 %s 已删除。\n", del_name);
            return;
        }
    }
    printf("没有找到该学生!\n");
}

9.排序功能

/
// 按照学生成绩排序
void sort_students(int ascending, StudentList *P)
{
    if (P->count <= 1)
    {
        return; // 如果学生数量为0或1,无需排序
    }

    Student temp;
    for (int i = 0; i < P->count - 1; i++)
    {
        for (int j = 0; j < P->count - i - 1; j++)
        {
            // 根据ascending参数决定升序还是降序
            if ((ascending && P->students[j].score > P->students[j + 1].score) ||
                (!ascending && P->students[j].score < P->students[j + 1].score))
            {
                // 交换学生信息
                temp = P->students[j];
                P->students[j] = P->students[j + 1];
                P->students[j + 1] = temp;
            }
        }
    }
}

10.显示菜单功能

void showMenu()
{
    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.排序");
    printf("\n============================\n");
}

11.系统登录模块

采用明文储存,只用作学习使用。

/  登录模块
#define MAX_ATTEMPTS 3 // 最大登录尝试次数

int passward_login()
{
    char password[50];                       // 存储用户输入的密码
    int attempts = 0;                        // 登录尝试次数
    const char *default_password = "123456"; // 默认密码

    printf("正在登陆系统!\n");

    while (attempts < MAX_ATTEMPTS)
    {
        printf("请输入学生管理系统的登录密码!第%d次登录: ", attempts + 1);
        fgets(password, sizeof(password), stdin);

        // 去掉换行符
        password[strcspn(password, "\n")] = '\0';

        if (strcmp(password, default_password) == 0)
        {
            printf("系统登录成功!\n");
            return 0; // 登录成功,退出程序
        }
        else
        {
            printf("系统登录失败!请重新输入密码。\n");
            attempts++;
        }
    }

    printf("密码输入错误次数过多,退出系统!\n");
    return 1; // 登录失败,退出程序
}
//

12.main函数

首先建立了一个StudentList类,初始化容量为10,尝试加载之前保存的学生信息;

循环里面主要是操作选择,对应之前的函数功能。

int main()
{
    // passward_login();

    StudentList list;
    InitStudentList(&list, 10); // 初始容量为10

    // 尝试加载之前保存的学生信息
    loadStudentsFromFile(&list, "students.dat");

    int choice;
    const char *filename = "students.dat"; // 学生信息存储文件

    while (1)
    {
        showMenu();

        printf("请选操作: ");
        scanf("%d", &choice);

        switch (choice)
        {
        case 1:
            AddStudentList(&list);
            break;
        case 2:
            displayStudent(&list);
            break;
        case 3:
            saveStudentsToFile(&list, filename);
            break;
        case 4:
            loadStudentsFromFile(&list, filename);
            break;
        case 5:
            saveStudentsToFile(&list, filename); // 确保退出前保存最新数据
            freeStudent(&list);
            printf("已退出系统。\n");
            return 0;
        case 6:
            Search_stu(&list);
            break;
        case 7:
            Student_information_statistics(&list);
            break;
        case 8:
            modify_stu_information(&list);
            break;
        case 9:
            delete_stu(&list);
            break;
        case 10:
            printf("降序输入:0,升序输入:1\n");
            int ascending = 0;
            scanf("%d", &ascending);
            sort_students(ascending, &list);
            printf("排序后的学生列表为:");
            displayStudent(&list);
            break;
        default:
            printf("无效的选择,请重新选择。\n");
        }
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值