C语言学生管理系统(支持增删改查以及排序)

多文件编程实现学生管理系统

使用结构体以及函数提高了代码的复用性

每个函数三要素都做了详细注释

1.main.c

#include <stdio.h>

#include "calen.h"

int main(int argc, const char *argv[])
{
    int chose; //chose为用户的选择,1-6
    int ret;
    //1.定义一个结构体类型为class_t cls的名为cls的变量用来表示班级
    class_t cls;
    //2.初始化班级内的学生人数
    cls.n = -1; //访问claas_t内部的n(当前学生人数) 从0到29,总计30 -1表示当前班级没人

    while (1)
    {
        //打印表头
        puts("***********************欢迎进入学生管理系统*********************");
        puts("************1.添加 2.删除 3.修改 4.查询 5.排序 6.退出************");
        puts("*************************************************************");

        printf("输入您的选择:");
        scanf("%d", &chose);
        while (getchar() != '\n')
            ; //处理垃圾字符,每次scanf后尽量处理 getchar获取的是’\n’一直为真
        switch (chose)
        {
        case ADDSTU: //1.添加学生
            add_studen(&cls);
            break;
        case DELSTU: //2.删除学生
            ret = del_student(&cls);
            printf("删除了%d个学生\n", ret);
            break;
        case MODSTU: //3.修改学生
            modify_student(&cls);
            break;
        case CHKSTU: //4.查询学生
            show_student(&cls);
            break;
        case SOTSTU: //5.排序,按照成绩
            sort_student(&cls);
            break;
        case QITSTU: //6.退出
            printf("退出学生管理系统,欢迎下次使用\n");
            break;
        default:
            printf("选择错误,请重新选择\n");
            continue; //continue代表退出本层的本次循环
        }
    }
    return 0;
}

2.stu.c

#include "calen.h"

//功能:判断班级内学生人数是否为空
//参数:班级的地址
//返回值:成功返回1(代表班级人数满),否则返回0
int class_stu_full(class_t *cls)
{
    return cls->n >= (MAXSTU - 1) ? 1 : 0; //条件运算符,表达式为真返回1,否则返回0
}
// 1.添加功能的实现
//功能:从终端输入学生的姓名,性别,分数
//参数:学生的结构体指针
//返回值:-1代表插入信息失败,0为成功
int input_stu_info(stu_t *stu)
{
    {
    again:                                                              //goto只能在当前函数内跳转,可以向前跳转,也可以向后跳转
        printf("请输入(name sex score");                               //goto一般用在统一出错处理
        int ret = scanf("%s %c %d", stu->name, &stu->sex, &stu->score); //scanf的返回值为输入占位符的个数
        if (ret != 3)
        {                                     //返回值用ret接 3代表成功,其他值代表失败
            printf("输入错误,请重新输入\n"); //此处goto代表输入错误就一直输入,直到输入正确为止
            while (getchar() != '\n')
                ; //吃掉垃圾字符
            goto again;
        }
        while (getchar() != '\n')
            ; //吃掉垃圾字符
        if (stu->sex != 'm' && stu->sex != 'w')
        { //只能输入'm'和'w'两个字符,其他都为错误
            printf("性别输入有误,请重新输入\n");
            goto again;
        }
        if (stu->score < 0 || stu->score > 100)
        {
            printf("分数输入错误,请重新输入\n");
            goto again;
        }
        return 0;
    }
}

//功能:向班级内添加学生信息
//参数:班级的指针
//返回值:-1代表添加信息失败。0为成功
int add_studen(class_t *cls)
{
    //1.添加之前判断班级内的人数是否已经满了
    if (class_stu_full(cls))
    { //调用函数判断,实参为班级人数,次函数返回值1代表满
        printf("班级内人数已满");
        return -1;
    }
    //2.如果没有满,就添加学生,输入学生信息
    input_stu_info(&cls->stu[++(cls->n)]); //调用函数,cls->n 为当前学生人数,必须随着插入人数的增加而增加
    //3.如果成功返回 0
    return 0;
}

//4.查询功能的实现
//功能:展示所有学生的信息
//参数:班级的指针
//返回值:无
void show_student(class_t *cls)
{ //将学生信息遍历一次,使用for循环
    for (int i = 0; i < cls->n; i++)
    {
        printf("name=%-10s sex=%c score=%d\n", cls->stu[i].name, cls->stu[i].sex, cls->stu[i].score);
    }
}

//功能:判断班级内人数是否为空
//参数:班级的指针
//返回值:为空返回真,否则返回0
int class_stu_empty(class_t *cls)
{
    return cls->n == -1 ? 1 : 0;
}

//2.删除功能的实现
//功能:根据输入的学生姓名,删除对应的学生
//参数:班级的指针
//返回值:成功返回删除的学生个数,失败则返回-1
int del_student(class_t *cls)
{
    char name[20] = {0};
    //1.判断班级是否为空
    if (class_stu_empty(cls))
    {
        printf("班级内没有学生\n");
        return -1;
    }
    //2.输入删除想要删除的学生名单
    printf("请输入想要删除的学生\n");
    scanf("%s", name);
    while (getchar() != '\n')
        ;
    //3.拿输入的学生姓名和班级内的学生进行比较
    int i = 0, j = 0;
    for (i = 0, j = 0; i < cls->n; i++)
    {
        if (strcmp(name, (cls->stu[i].name)))
        {                              //输入学生的姓名和班级内某个学生相等的时间不进入if语句,i一直加
            cls->stu[j] = cls->stu[i]; //不相等就进入if语句,将i此时的下标给到j,完成位置的替换
            j++;
        }
    }
    //4.修改班级内n的值
    cls->n -= (i - j);
    //5.返回值
    return (i - j);
}
//5.排序功能的实现
//功能:根据学生的成绩进行排序(冒泡排序 优化版)
//参数:
//返回值:
int sort_student(class_t *cls)
{
    stu_t stu;
    int i, j, flag;
    for (i = 0; i < cls->n; i++)
    {
        for (j = 0; j < cls->n - i; j++)
        {
            if (cls->stu[j].score > cls->stu[j + 1].score)
            {
                stu = cls->stu[j];
                cls->stu[j] = cls->stu[j + 1];
                cls->stu[j + 1] = stu;
                flag = 1;
            }
        }
        if (0 == flag)
        { //表示上一步没有进入if循环,此时已经有序排列,减少了多余的排列
            break;
        }
    }
}

//3.根据姓名修改学生信息
//功能:根据输入的学生姓名修改信息
//参数:班级的指针
//返回值:
int modify_student(class_t *cls)
{
    char name[20] = {0};
    //1.判断班级内是否没有人
    if (class_stu_full(cls))
    {
        printf("班级内没有人,修改失败\n");
        return -1;
    }
    //2.输入学生名字
    printf("请输入想要修改的学生姓名");
    scanf("%s", name);
    while (getchar() != '\n')
        ;
    //3.通过名字查找想要修改的学生的姓名
    int flags = 0;
    int which = 0;
    for (int i = 0; i < cls->n; i++)
    {
        if (strcmp(name, cls->stu[i].name) == 0)
        { //strcmp逐位比较两个字符串的ascii码,相等返回0
            printf("%d.name=%-10s sex=%c score=%d\n", i, cls->stu[i].name, cls->stu[i].sex, cls->stu[i].score);
            flags = 1; // 执行if语句后,改变flags的值,表示查询到学生
        }
        if (0 == flags)
        {
            printf("查不到此人,请重新输入\n");
            return -1;
        }
        //4.输入想要修改的下标,防止有名字相同的情况

        printf("请输入想要修改的学生的下标:");
        scanf("%d", &which);
    }
    //5.输入新的信息
    input_stu_info(&cls->stu[which]);
}

3.stu.h

#ifndef __CALEN_H__
#define __CALEN_H__

#include <stdio.h>  //包含printf等函数的头文件
#include <string.h> //包含strcmp,strcpy,strcat等函数的头文件
#include <stdlib.h> //包含getchar等函数的头文件

#define ADDSTU 1 //1.添加
#define DELSTU 2 //2.删除
#define MODSTU 3 //3.修改
#define CHKSTU 4 //4.查询modify_student(class_t  *cls)
#define SOTSTU 5 //5.排序
#define QITSTU 6 //6.退出

#define MAXSTU 30 //最大可容纳的学生人数
typedef struct
{
    char name[20]; //定义了一个数组用来保存姓名
    char sex;      // 性别
    int score;     //分数
} stu_t;           //重新定义了一个类型为stu_t的结构体类型

typedef struct
{
    stu_t stu[MAXSTU]; //班级内能容纳的学生人数
    int n;             //班级内的当前学生人数
} class_t;             //重新定义了一个类型为class_t的结构体类型

int add_studen(class_t *cls);     //1.添加函数
void show_student(class_t *cls);  //4.查询函数
int modify_student(class_t *cls); //3.修改
int del_student(class_t *cls);    //2.删除
int sort_student(class_t *cls);   //5.排序

#endif
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值