C语言——学生管理系统(V3.0版)

😁经历了一个月的C语言学习,将学习成果奉上,学生成绩管理系统,涵盖了很多C语言的知识点,做法很多,链表和结构体的都有,我是用的结构体,但巧妙的利用动态存储的方式将学生的信息存储到文件中。------结尾附上代码😀

一、实现效果

👏登录界面

采用密码验证方式进入系统,错误则重复输入,隐藏密码

 👋主菜单页面

 ******************通过输入对应的数字进到对应的系统************************

✍学生个人信息管理页面

 ******************输入对应数字进行对应的操作***************************

💪学生成绩管理系统

二、实现思路 

  • 利用结构体的特点,将增加的学生信息先保存在结构体中
  • 分模块编写,增删改查,分函数写,再调用
  • 利用动态存储的方式分配空间
  • 考虑细节,判断输入的各种情况,比如学号唯一,指针空等
  • 文件操作,写入和读取,利用结构体变量来接

 三、功能说明

  • 👉主菜单进入子系统时,会进行初始化,结构体清空,经文件里的学生信息读取到结构体中,并进行容量检查
  • 👉增加学生信息:将学生信息添加到系统中(学号唯一判断,容量判断)
  • 👉删除学生信息:输入你要修改的学生学号删除对应学生信息
  • 👉修改学生信息:输入你要修改的学生学号删除对应学生信息
  • 👉查询学生成绩:输入你要查询的学生学号输出对应学生信息
  • 👉输出学生信息:输出表中所有的学生信息
  • 👉排序学生信息:根据学号进行降序排序
  • 👉退出系统:先将学生信息保存到文件中方便下次读取,然后释放内存,回到主菜单

 四、实现讲解

♈基本框架的搭建

                     **************************创建三个文件*****************************

 给大家解释下为什么要创建三个文件,首先,做项目,讲究的是编程手法和代码的简洁化,为我们在写代码时,需要将代码模块化,所谓的模块化就是,将函数封装,在主函数调用,这样搭建框架有助于大家思考下一步怎么做,所以博主建议大家在写时像上图这样,main.c里放主函数和主界面,student.h放函数的声明,结构体和枚举声明以及宏定义,而student.c编写要封装的函数和功能,通过main函数进行调用,这样子我们思路就会非常的清晰,一步一步完善我们的模块。

******************************************  开始啦 ********************************************************** 

🌎1.定义两个结构体,一个用来存放学生的个人信息,一个用来嵌套成员人数,记录表中成员的个数和容量,为待会写动态存储做准备

🌍2. 定义各个模块的函数,在.h文件里定义,模块化编程

声明好需要的函数,然后再分模块编写,

   这里提一点,大家要养成好的习惯,函数命名时尽量用翻译,将中文翻译好这个模块是什么功能的进行命名,不然久了回来看项目时,就不知道那个模块是什么功能了,包括定义变量也一样,,不要总是 i, j, a, b这样声明很容易弄混,因为代码量很多,有时候会冲突导致你找很久,所以尽量将功能翻译成中文使用。

 

 🌏3.菜单页面的编写

         这个就没什么好说的,大家的美化技能应该比我的强大吧,可以根据自己的想法来哦

 

 🌕4.主函数的排布

  • 这里的登录界面我们后面再讲,因为会涉及到密码的处理
  • 定义静态全局变量input用来存储输入的指令数字
  • 通过do--while 来嵌套switch来循环输入指令来处理
  • system函数的用法很多,这里是冻结窗口的意思,可以停下来让你观察打印的变化
  • 这里的switch就是输入相应的数字进入不同的系统了

 ♉编写初始化的函数 

            *********************************增容函数***********************************

  • 解释下,这里的函数的传进来的参数是存放学生人数的结构体变量,在主函数有定义的
  • 往下,比较容量和sz的数值是否相等来判断是否需要增容
  • realloc是调整空间的函数,返回的是调整后空间的大小
  • 再往下就是增容部分的赋值,将扩容后的空间给到结构体

            *********************************初始化函数***********************************

     进行系统运行时的初始化,首先会开辟3个结构体大小的空间来存放数据,然后读取文件的数据存放进来,期间会进行一个容量的判断

//*****初始化个人信息--动态分配内存,先分配3个,超过3个再给2个******
int InitContact(Contact *pc)
{
	assert(pc); //如果指针为空就会返回信息
	pc->sz = 0;
	pc->data = (PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		printf("InitContact::%s\n", strerror(errno));
		return 1;
	}
	pc->capacity = DEFAULT_SZ;
	//加载文件的信息到通讯录中
	 LoadStudent(pc);
    // LoadScore(qs);  //读取成绩信息
	return 0;
}

            *********************************文件读取函数***********************************

  • 文件读取,一块一块读,定义一个临时的结构体变量来存放读取过来的数据,这样我们就不用考虑格式,用结构体变量存,顺序存储排放。
  • perror是检测到为空就会返回信息,防御式编程
  • 容量检测,超过3个后就会扩容两个,往后就判断,满了就扩容两个

             

            *********************************释放内存函数***********************************

 ♊功能函数的编写

            *********************************增加信息函数***********************************

  • 先检测容量是否足够,不够就进行扩容,这里封装好了,直接调用就行
  • 学号不能重复,这里进行判断,通过goto 语句进行跳转
  • 将输入的值放进结构体就行,这里就不多说了

            *********************************增加信息函数***********************************

  • 这里封装好一个查找函数,返回下标,为后面的函数做准备

            *********************************删除信息函数***********************************

  • 这里就用到了上面封装的函数,通过接收返回值进行判断,是否存在
  • 存在就执行删除,覆盖结构体的整个值

           *********************************排序函数***********************************

  • 根据学号排序,比较数值的大小
  • 用了字符转换整型的函数,因为学号前面定义类型错了,改的话比较麻烦

           *********************************写文件函数***********************************

  •  这个也没啥好说的,封装好的,但时候主函数调用,退出指令的时候自动将结构体的信息保存到外部文件中

剩下的一些查询函数大同小异,就不一一罗列了,大家可以看下代码。放在了结尾。 

♋登录界面 

  • 这里调用了#include <conio.h> 这个头文件,里面有个函数用来密码隐藏
  • 无非就是一些输入的判断,错误就循环输入
  • 可添加输入次数的判断
//**********************登录界面*********************
void Log_In()
{
    char password[MAX_PASSWORD_LENGTH];
    // 存储预定义的用户名和密码
    char predefined_password[] = "password";
     char input[10];
    printf("\n");
    printf("\033[1;34m███╗   ██╗ ███████╗ ██████╗ ██████╗ ██╗   ██╗\033[0m\n");
    printf("\033[1;34m████╗  ██║ ██╔════╝██╔═══██╗██╔══██╗╚██╗ ██╔╝\033[0m\n");
    printf("\033[1;34m██╔██╗ ██║ ███████╗██║   ██║██████╔╝ ╚████╔╝\033[0m\n");
    printf("\033[1;34m██║╚██╗██║ ╚════██║██║   ██║██╔══██╗  ╚██╔╝\033[0m\n");
    printf("\033[1;34m██║ ╚████║ ███████║╚██████╔╝██████╔╝   ██║\033[0m\n");
    printf("\033[1;34m╚═╝  ╚═══╝ ╚══════╝ ╚═════╝ ╚═════╝    ╚═╝\033[0m\n");
    printf("\n");

    printf("\033[36m欢迎使用学生管理系统\n\n");

    printf("用户名:admin \n\n");
    int j = 100,i;
    while (j--) {
        printf("请输入密码 : " );

        // 隐藏密码输入
        int index = 0;
        char ch;
        for(i=0;i<100;i++)
        {
            ch = getch();
            if (ch == 13) // 如果用户按下回车键
                break;
            if (ch == 8 && index > 0) { // 如果用户按下退格键
                putchar('\b');
                putchar(' ');
                putchar('\b');
                index--;
                continue;
            }
            if (ch != 8) { // 忽略退格键
                putchar('*'); // 显示'*'而不是实际输入的字符
                password[index] = ch;
                index++;
            }
        }
        password[index] = '\0'; // 在密码末尾添加null终止符

        if (strcmp(password, predefined_password) == 0) {
            printf("\n\033[1;32m正在登录...\033[0m\n");
            Sleep(2000);
            printf("\n登录成功!\n");
            return;
        } else {
            printf("\n密码错误,请重试。\n");
        }
    }

}

代码分享 :

        存放信息的 文件会在执行文件时自动创建,有些编辑器需要创建项目才能同时运行多个.c文件,大家可以根据自己的编辑器类型来创建,我用的是vscode, c-free

main.c

#include <stdio.h>
#include <stdlib.h>
#include "student.h"

// 学生个人信息菜单
void menu_a()
{
    system("cls"); // 清屏
    printf("\t\t****************************************************************\n");
    printf("\t\t\033[37m***********           \033[34m学生个人信息管理         \033[37m     ************\n");
    printf("\t\t----------------------------------------------------------------\n");

    printf("\t\t***********     \033[32m     1 \033[37m---- 增加学生信息             ***********\n");
    printf("\t\t***********     \033[32m     2 \033[37m---- 删除学生信息             ***********\n");
    printf("\t\t***********     \033[32m     3 \033[37m---- 修改学生信息             ***********\n");
    printf("\t\t***********     \033[32m     4 \033[37m---- 查询学生信息             ***********\n");
    printf("\t\t***********     \033[32m     5 \033[37m---- 输出学生信息             ***********\n");
    printf("\t\t***********     \033[32m     6 \033[37m---- 排序学生信息             ***********\n");
    printf("\t\t***********     \033[32m     0 \033[37m---- 退出管理系统             ***********\n");
    printf("\t\t***************************************************************\n");

    printf("\033[35m");
    printf("\t\t请选择你的操作(数字):");
}

// 成绩管理
void menu_b()
{
    system("cls"); // 清屏
    printf("\033[37m=======================\033[34m学生成绩信息管理\033[37m============================\n");
    printf("---------------------------功能菜单------------------------------\n");
    printf("\t\t\t\033[32m1\033[37m--录入学生成绩信息\n");
    printf("\t\t\t\033[32m2\033[37m--删除学生成绩信息\n");
    printf("\t\t\t\033[32m3\033[37m--修改学生成绩\n");
    printf("\t\t\t\033[32m4\033[37m--查询单个学生的成绩\n");
    printf("\t\t\t\033[32m5\033[37m--查询所有学生成绩\n");
    printf("\t\t\t\033[32m6\033[37m--学生成绩排序\n");
    printf("\t\t\t\033[32m7\033[37m--根据学号排序\n");
    printf("\t\t\t\033[32m8\033[37m--保存学生信息\n");
    printf("\t\t\t\033[32m9\033[37m--查看班级平均分\n");
    printf("\t\t\t\033[32m0\033[37m--退出系统\n");
    printf("------------------------------------------------------------------\n");

    printf("\033[35m");
    printf("\t\t请选择你的操作(数字):");
}
// 总菜单页面
void menuAll()
{
    system("cls"); // 清屏
    printf("\t\t****************************************************************\n");
    printf("\t\t\033[37m***********           \033[34m学生信息管理系统V3.0版         \033[37m   ********\n");
    printf("\t\t----------------------------------------------------------------\n");

    printf("\t\t***********     \033[32m     1 \033[37m---- 个人信息管理系统-》        *********\n");
    printf("\t\t***********     \033[32m     2 \033[37m---- 成绩信息管理系统-》        **********\n");
    printf("\t\t***********     \033[32m     0 \033[37m---- 退出管理系统              **********\n");

    printf("\t\t****************************************************************\n");

    printf("\033[35m");
    printf("\t\t请选择你要进入的系统(数字):");
}

// 创建个人信息结构体变量
Contact con;
// 创建成绩信息结构体变量
Crowd str;
//****************************************************************
//**************          个人信息菜单             ****************
//****************************************************************
void Information()
{
    short input_a = 0;
    do
    {
        menu_a(); // 菜单
        scanf("%d", &input_a);
        switch (input_a)
        {
        case ADD:
            // 增加
            add_student(&con);
            break;
        case DEL:
            // 删除
            delete_student(&con);
            break;
        case MODIFY:
            // 修改
            modify_student(&con);
            break;
        case QUERY:
            // 查询
            query_student(&con);
            break;
        case OUTPUT:
            // 输出
            output_student(&con);
            break;
        case SORT:
            // 学号排序
            sort_student(&con);
            break;
        case EXIT:
            // 退出--保存文件
            save_student(&con);
            DestroyContact(&con);
            break;
        default:
            printf("\t\t\033[31m输入错误,请重新输入!\033[37m\n");
            input_a = 1;
            break;
        }
        system("pause");
    } while (input_a);
}
//****************************************************************
//**************          成绩信息菜单             ****************
//****************************************************************
void Score()
{
    short input_b = 0;
    do
    {
        menu_b(); // 菜单
        scanf("%d", &input_b);
        switch (input_b)
        {
        case ADD:
            // 增加
            add_score(&str);
            break;
        case DEL:
            // 删除
            delete_score(&str);
            break;
        case MODIFY:
            // 修改
            modify_score(&str);
            break;
        case QUERY:
            // 查询个人
            query_score(&str);
            break;
        case OUTPUT:
            // 查询所有
            output_score(&str);
            break;
        case SORT:
            // 成绩排序
            sort_avge_score(&str);
            break;
        case SORT_ID:
            // 学号排序
            sort_ID_score(&str);
            break;
        case Save_score:
            // 保存信息
            Save_Score_File(&str);
            break;
        case Examine:
            // 查看班级平均分
            Class_avge_score(&str);
            break;
        case EXIT:
            // 退出--保存文件
            Save_Score_File(&str);
            Destroy_Crowd(&str);
            printf("\t\t  感谢使用!!!!!!!\n");
            return;
        default:
            printf("\t\t\033[31m输入错误,请重新输入!\033[37m\n");
            break;
        }
        system("pause");

    } while (input_b);
}
//****************************************************************
//**********            主函数                    ****************
//****************************************************************
static int input; // 静态全局
int main()
{

    // 登录界面
    Log_In();
	//system("color 8A");
    do
    {
        menuAll(); // 总菜单
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            // 个人信息管理
            InitContact(&con); // 初始化
            system("pause");
            Information();
            continue;
        case 2:
            // 成绩信息管理
            InitContact_grade(&str); // 初始化
            system("pause");
            Score();
            continue;
        case 0:
            // 退出系统
            // Exit();
            break;
        default:
            printf("\t\t\033[31m输入的指令有误,请重新输入\n");
            break;
        }
        system("pause");
    } while (input);
    return 0;
}

student.c 

#include <stdio.h>
#include "student.h"
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <conio.h> // 用于隐藏密码输
#include <windows.h>

//***********增容的函数************判断是否需要增容****************
void CheckCapacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
		if (ptr == NULL)
		{
			printf("AddContact::%s\n", strerror(errno));
			return;
		}
		else
		{
			pc->data = ptr;
			pc->capacity += INC_SZ;
			printf("\t\t\033[31m增容成功\n");
		}
	}
    //system("pause");
}

//*************个人信息文件读取***************
void LoadStudent(Contact *pc)
{
    FILE *fp = fopen("student.txt", "rb");
    if (fp == NULL)
    {
        perror("LoadStudent");
        return;
    }
    PeoInfo temp = {0}; // 定义结构体变量对读出的文件进行接收
    // 读文件
    while (fread(&temp, sizeof(PeoInfo), 1, fp) == 1) // 成功返回读写的块数,失败返回0
    {
        CheckCapacity(pc);
        pc->data[pc->sz] = temp;
        pc->sz++;
    }
    // 关闭文件
    fclose(fp);
    fp = NULL;
    printf("\t\t\033[33m1--个人信息读取成功\n");
}

//***********成绩信息文件读取*******************
void LoadScore(Crowd *qs)
{
    // 打开文件
    FILE *fp = fopen("student_score.txt","rb");
    if(fp == NULL)
    {
        perror("LoadScore");
        return;
    }
    Result tmp = {0}; //定义一个新的结构体变量进行接收
    while(fread(&tmp,sizeof(Result),1,fp) == 1) //成功返回写的数量 失败返回0
    {
        CheckCapacity_grade(qs);
        qs->data[qs->count] = tmp;
        qs->count++;
    }

    //关闭文件
    fclose(fp);
    fp = NULL;
    printf("\t\t\033[33m2--成绩信息读取成功\n");
}

//*****初始化个人信息--动态分配内存,先分配3个,超过3个再给2个******
int InitContact(Contact *pc)
{
	assert(pc); //如果指针为空就会返回信息
	pc->sz = 0;
	pc->data = (PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		printf("InitContact::%s\n", strerror(errno));
		return 1;
	}
	pc->capacity = DEFAULT_SZ;
	//加载文件的信息到通讯录中
	 LoadStudent(pc);
    // LoadScore(qs);  //读取成绩信息
	return 0;
}


//*********释放掉内存***********
void DestroyContact(Contact* pc)
{
	assert(pc);
	free(pc->data);
	pc->data = NULL;
    printf("\t\t内存释放成功!\n");
}

//********动态 增加学生********
void add_student(Contact *pc)
{
    assert(pc);
    int i;
	//增容
	CheckCapacity(pc);
    dir:
    printf("\t\t\033[32m请输入学生学号:");
    scanf("%s", pc->data[pc->sz].ID);
    // 判断学号是否重复
    for (i = 0; i < pc->sz; i++)
    {
        if (strcmp(pc->data[i].ID, pc->data[pc->sz].ID) == 0)
        {
            printf("\t\t\033[31m学号已存在\n");
            goto dir;
        }
    }
    printf("\t\t请输入学生的姓名: ");
    scanf("%s", pc->data[pc->sz].name);
    printf("\t\t请输入学生性别:");
    scanf("%s", pc->data[pc->sz].sex);
    printf("\t\t请输入学生专业:");
    scanf("%s", pc->data[pc->sz].major);
    printf("\t\t请输入学生的班级: ");
    scanf("%s", pc->data[pc->sz].grade);
    printf("\t\t请输入学生的电话:");
    scanf("%s", pc->data[pc->sz].phone);
    pc->sz++; // 位移一位
    printf("\t\t添加成功\n");
}

// **********输出全部学生信息****************
void output_student(Contact *pc)
{
    assert(pc);
    int i;
    if (pc->sz == 0)
    {
        printf("\t\t\033[31m学生信息表为空,请增加学生信息!\n\n");
        return;
    }
    printf("\t ===================================================================================\n");
    for (i = 0; i < pc->sz; i++)
    {
        printf("\t\033[33m |%-10s\t%-15s\t%-12s\t%-15s\t%-12s\t%-12s\n", "学号", "姓名", "性别", "专业", "班级", "电话");
        printf("\t\033[37m |%-10s\t%-15s\t%-12s\t%-15s\t%-12s\t%-12s\n",
               pc->data[i].ID, pc->data[i].name,
               pc->data[i].sex, pc->data[i].major,
               pc->data[i].grade, pc->data[i].phone);
    }
    printf("\t ===================================================================================\n");
}

// *********查找函数--通过学号查找*************
int FindByName(Contact *pc, char *num)
{
    assert(pc);
    int i;
    for (i = 0; i < pc->sz; i++)
    {
        if (strcmp(pc->data[i].ID, num) == 0)
        {
            return i; // 返回位置下标
        }
    }
    return -1; // 没有则返回-1
}

//************ 删除学生信息*******************
void delete_student(Contact *pc)
{
    assert(pc);
    int i;
    char num[20];
    if (pc->sz == 0)
    {
        printf("\t\t\033[31m学生信息表为空,无删除\n\n");
        return;
    }
    printf("\t\t请输入要删除的学号:");
    scanf("%s", num);
    // 1.查找学生
    int pos = FindByName(pc, num); // 接收返回值
    if (pos == -1)
    {
        printf("\t\t该学号不存在\n");
        return;
    }
    // 2.删除
    for (i = pos; i < pc->sz - 1; i++)
    {
        pc->data[i] = pc->data[i + 1];
    }
    pc->sz--;
    printf("\t\t删除成功\n");
}

// ****************根据学号查询信息************
void query_student(Contact *pc)
{
    assert(pc);
    int i;
    if (pc->sz == 0)
    {
        printf("\t\t\033[31m学生信息表为空,无查询\n\n");
        return;
    }
    char num[20];
    printf("\t\t请输入要查询的学号:");
    scanf("%s", num);
    int pos = FindByName(pc, num);
    if (pos == -1)
    {
        printf("\t\t该学号不存在\n");
        return;
    }
    printf("\n\t\t \033[34m 你要查询学号为 %s学生信息如下:\n", pc->data[pos].ID);
    printf("\t\t%-10s\t%-15s\t%-12s\t%-15s\t%-12s\t%-12s\n", "学号", "姓名", "性别", "专业", "班级", "电话");
    printf("\t\t%-10s\t%-15s\t%-12s\t%-15s\t%-12s\t%-12s\n",
           pc->data[pos].ID, pc->data[pos].name,
           pc->data[pos].sex, pc->data[pos].major,
           pc->data[pos].grade, pc->data[pos].phone);
}

//************* 修改*****************
void modify_student(Contact *pc)
{
    assert(pc);
    int i;
    if (pc->sz == 0)
    {
        printf("\t\t\033[31m学生信息表为空,无法修改\n\n");
        return;
    }
    char num[20];
    printf("\t\t请输入要修改的学生的学号:");
    scanf("%s", num);
    int pos = FindByName(pc, num);
    if (pos == -1)
    {
        printf("\t\t查询不到,没有该学生");
        return;
    }
    char str[20];
    //输入信息更改表里的信息
    dir:
    printf("\t\t请输入学生学号:");
    scanf("%s", str);
    // 判断学号是否重复
    for (i = 0; i < pc->sz; i++)
    {
        if (strcmp(pc->data[i].ID, str) == 0)
        {
            printf("\t\t\033[31m学号已存在\n");
            goto dir;
        }
    }
    strcpy(pc->data[pos].ID, str); // 将学号写进去
    // 继续写入信息
    printf("\t\t请输入学生的姓名: ");
    scanf("%s", pc->data[pos].name);
    printf("\t\t请输入学生性别:");
    scanf("%s", pc->data[pos].sex);
    printf("\t\t请输入学生专业:");
    scanf("%s", pc->data[pos].major);
    printf("\t\t请输入学生的班级: ");
    scanf("%s", pc->data[pos].grade);
    printf("\t\t请输入学生的电话:");
    scanf("%s", pc->data[pos].phone);
    printf("\t\t修改成功!\n");
}

// *********比较大小交换两个数值*************
void cmp_by_num(PeoInfo *str1, PeoInfo *str2)
{
    PeoInfo temp; // 定义一个第三结构体变量
    temp = *str1;
    *str1 = *str2;
    *str2 = temp;
}

//*********** 排序 ************************
void sort_student(Contact *pc)
{
    assert(pc);
    int i, j;
    if (pc->sz == 0)
    {
        printf("\n\t\t \033[31m无学生信息,无法排序\n");
        return;
    }
    for (i = 0; i < pc->sz - 1; i++) // 通过学号进行冒泡排序
    {
        for (j = 0; j < pc->sz - i - 1; j++)
        {
            if (atoi(pc->data[j].ID) > atoi(pc->data[j+1].ID)) //将字符串转换成整数进行比较
            {
                cmp_by_num(&pc->data[j], &pc->data[j + 1]);
            }
        }
    }
    printf("\t\t排序成功\n");
}

// ****************写文件**********************
void save_student(Contact *pc)
{
    assert(pc);
    // 打开文件
    FILE *fp = fopen("student.txt", "wb"); // 二进制写入
    if (fp == NULL)
    {
        perror("save_student");
        return;
    }
    // 写文件
    int i;
    for (i = 0; i < pc->sz; i++)
    {
        fwrite(&pc->data[i], sizeof(PeoInfo), 1, fp);
    }
    // 关闭文件
    fclose(fp);
    fp = NULL;
    printf("\t\t\033[33m保存成功,可安全退出\n");
}

//********************************************************************************8
//*******************        成绩信息管理           *******************************8
//********************************************************************************8
//*****初始化个人信息--动态分配内存,先分配3个,超过3个再给2个*******
int InitContact_grade(Crowd *qs)
{
	assert(qs);
	qs->count = 0;
	qs->data = (Result*)calloc(DEFAULT_SZ, sizeof(Result));
	if (qs->data == NULL)
	{
		printf("InitContact::%s\n", strerror(errno));
		return 1;
	}
	qs->capacity = DEFAULT_SZ;
	//加载文件的信息
    LoadScore(qs);  //读取成绩信息
	return 0;
}
//*****************释放掉内存************
void Destroy_Crowd(Crowd* qs)
{
	assert(qs);
	free(qs->data);
	qs->data = NULL;
    printf("\t\t内存释放成功!\n");
    system("pause");
}
//*********************检测增容的函数***********************
void CheckCapacity_grade(Crowd* qs)
{
	if (qs->count == qs->capacity)
	{
		Result* ptr = (Result*)realloc(qs->data, (qs->capacity + INC_SZ) * sizeof(Result));
		if (ptr == NULL)
		{
			printf("AddContact::%s\n", strerror(errno));
			return;
		}
		else
		{
			qs->data = ptr;
			qs->capacity += INC_SZ;
			printf("\t\t\033[31m增容成功\n");
		}
	}
}
//********************* 增加成绩信息************************
void add_score(Crowd *qs)
{
    assert(qs);
    int i;
    CheckCapacity_grade(qs);
    dir:
    printf("\t\t\033[32m请输入该学生的学号: ");
    scanf("%s", qs->data[qs->count].ID);
    for (i = 0; i < qs->count; i++)
    {
        if (strcmp(qs->data[i].ID, qs->data[qs->count].ID) == 0)
        {
            printf("\t\t\033[31m学号已存在\n");
            goto dir;
        }
    }
    printf("\t\t请输入学生的姓名:");
    scanf("%s", qs->data[qs->count].name);
    printf("\t\t请输入该学生的语文成绩:");
    scanf("%d", &qs->data[qs->count].language);
    printf("\t\t请输入该学生的数学成绩:");
    scanf("%d", &qs->data[qs->count].math);
    printf("\t\t请输入该学生的英语成绩:");
    scanf("%d", &qs->data[qs->count].English);
    All_avse(qs, qs->count); //总分和平均分的处理
    qs->count++; //位移一位
    printf("\t\t添加成功\n");
}

//*********************平均分和总分的处理********************
void All_avse(Crowd *qs,int num)
{
    assert(qs);
    //总分
    qs->data[num].Total=(qs->data[num].language)+
                                (qs->data[num].English)+
                                (qs->data[num].math);
    //平均分
    qs->data[num].average=((qs->data[num].Total)/3);
}

//********************* 输出所有学生成绩信息*******************
void output_score(Crowd *qs)
{
    assert(qs);
    int i;
    if (qs->count == 0)
    {
        printf("\t\t\033[31m无学生成绩信息,请添加后再尝试出输出\n");
        return;
    }
    printf("  \t ============================================================================\n");
    for (i = 0; i < qs->count; i++)
    {

        printf("  \t\033[33m |%-10s\t%-15s\t%-12s\t%-15s\t%-12s\t%-12s\t%-12s\n", "学号", "姓名", "语文成绩", "数学成绩", "英语成绩","总分","平均分");
        printf("  \t\033[37m |%-10s\t%-15s\t%-12d\t%-15d\t%-12d\t%-12d\t%-12d\n",
               qs->data[i].ID, qs->data[i].name,
               qs->data[i].language, qs->data[i].math,
               qs->data[i].English,qs->data[i].Total,
               qs->data[i].average); 
    }
    printf("  \t ============================================================================\n");

}
//************ 封装的查询函数**********************
int FindByNumber(Crowd *qs, char *num)
{
    assert(qs);
    int i;
    for (i = 0; i < qs->count; i++)
    {
        if (strcmp(qs->data[i].ID, num) == 0)
        {
            return i; // 返回位置下标
        }
    }
    return -1; // 没有则返回-1
}

// ************删除成绩*********************
void delete_score(Crowd *qs)
{
    assert(qs);
    int i;
    char num[20];
    if (qs->count == 0)
    {
        printf("\t\t\033[31m表里无学生成绩信息,删除失败\n");
        return;
    }
    printf("\t\t请输入你要删除的学生的学号:");
    scanf("%s", num);
    int pos = FindByNumber(qs, num); // 获取返回值进行判断
    if (pos == -1)
    {
        printf("t\t\033[31m要删除的人不存在");
        return;
    }
    for (i = pos; i < qs->count - 1; i++)
    {
        qs->data[i] = qs->data[i + 1]; // 将元素往前移将要删除的覆盖
    }
    qs->count--;
    printf("\t\t删除成功\n");
}

//***************** 修改信息 ***************************
void modify_score(Crowd *qs)
{
    assert(qs);
    char num[20];
    if (qs->count == 0)
    {
        printf("\t\t\033[31m无学生成绩信息,修改失败\n");
        return;
    }
    printf("\t\t请输入你要修改的学生的学号:");
    scanf("%s", num);
    int pos = FindByNumber(qs, num); // 获取返回值进行判断
    if (pos == -1)
    {
        printf("t\t\033[31m要修改的人不存在");
        return;
    }
    int i;
    char clos[20];
    dir:
    printf("\t\t\033[32m请输入该学生的学号: ");
    scanf("%s", clos);
    for (i = 0; i < qs->count; i++)
    {
        if (strcmp(qs->data[i].ID, clos) == 0)
        {
            printf("\t\t\033[31m学号已存在\n");
            goto dir;
        }
    }
    strcpy(qs->data[pos].ID,clos);
    printf("\t\t请输入学生的姓名:");
    scanf("%s", qs->data[pos].name);
    printf("\t\t请输入该学生的语文成绩:");
    scanf("%d", &qs->data[pos].language);
    printf("\t\t请输入该学生的数学成绩:");
    scanf("%d", &qs->data[pos].math);
    printf("\t\t请输入该学生的英语成绩:");
    scanf("%d", &qs->data[pos].English);
    All_avse(qs,pos); //总分和平均分的处理

    printf("\t\t修改成功\n");

}

//********************* 查询个人成绩***********************
void query_score(Crowd *qs)
{
    assert(qs);
    char num[20];
    if (qs->count == 0)
    {
        printf("\t\t\033[31m无学生成绩信息,查询失败\n");
        return;
    }
    printf("\t\t请输入你要查询的学生的学号:");
    scanf("%s", num);
    int pos = FindByNumber(qs, num); // 获取返回值进行判断
    if (pos == -1)
    {
        printf("t\t\033[31m要查询的人不存在");
        return;
    }
    printf("  \t ============================================================================\n");
    printf("  \t\033[33m |%-10s\t%-15s\t%-12s\t%-15s\t%-12s\n", "学号", "姓名", "语文成绩", "数学成绩", "英语成绩");
    printf("  \t\033[37m |%-10s\t%-15s\t%-12d\t%-15d\t%-12d\n",
           qs->data[pos].ID, qs->data[pos].name,
           qs->data[pos].language, qs->data[pos].math,
           qs->data[pos].English);
    printf("  \t ============================================================================\n");
}

//*****************交换位置******************
void Exchange_num(Result *arr1 , Result *arr2)
{
    Result temp;//定义第三个结构体变量
    temp=*arr1;
    *arr1=*arr2;
    *arr2=temp;
}
//************根据--平均分排序*************
void sort_avge_score(Crowd *qs)
{
    assert(qs);
    int i, j;
    if (qs->count == 0)
    {
        printf("\n\t\t \033[31m无学生信息,无法排序\n");
        return;
    }
    for (i = 0; i < qs->count - 1; i++) // 通过平均分进行冒泡排序
    {
        for (j = 0; j < qs->count - i - 1; j++)
        {
            if (qs->data[j].average < qs->data[j + 1].average)
            {
                Exchange_num(&qs->data[j],&qs->data[j+1]);
            }
        }
    }
    printf("\t\t排序成功\n");
}
//************根据--学号排序**************
void sort_ID_score(Crowd *qs)
{
    assert(qs);
    int i, j;
    if (qs->count == 0)
    {
        printf("\n\t\t \033[31m无学生信息,无法排序\n");
        return;
    }
    for (i = 0; i < qs->count - 1; i++) // 通过学号进行冒泡排序
    {
        for (j = 0; j < qs->count - i - 1; j++)
        {
            if (strcmp(qs->data[j].ID,qs->data[j+1].ID) > 0)
            {
                Exchange_num(&qs->data[j],&qs->data[j+1]);
            }
        }
    }
    printf("\t\t排序成功\n");
}

//************保存信息到文件**************
void Save_Score_File(Crowd *qs)
{
    assert(qs);
    //打开文件
    FILE *fp = fopen("student_score.txt","wb");
    if(fp == NULL)
    {
         perror("Save_score_File");
        return;
    }

    //写文件
    int i;
    for(i=0;i<qs->count;i++)
    {
        fwrite(&qs->data[i],sizeof(Result),1,fp);
    }

    //关闭文件
    fclose(fp);
    fp = NULL;
    printf("\t\t信息保存成功\n");
}
//*****************查看班级平均分********************
void Class_avge_score(Crowd *qs)
{
    assert(qs);
    if(qs->count==0)
    {
        printf("\t\t无成绩信息,请重新选择\n");
        return;
    }
    short i,all_avge1=0,all_avge2=0,all_avge3=0;
    for(i=0;i<qs->count;i++)
    {
        all_avge1+=qs->data[i].language;
        all_avge2+=qs->data[i].math;
        all_avge3+=qs->data[i].English;
    }
    printf("  \t ============================================================================\n");
    printf("  \t\033[33m |%-10s\t%-15s\t%-12s\n",  "语文平均分", "数学平均分", "英语平均分");
    printf("  \t\033[33m |%-10d\t%-15d\t%-12d\n",all_avge1/qs->count,all_avge2/qs->count,all_avge3/qs->count);
    printf("  \t ============================================================================\n");
}


//**********************登录界面*********************
void Log_In()
{
    char password[MAX_PASSWORD_LENGTH];
    // 存储预定义的用户名和密码
    char predefined_password[] = "password";
     char input[10];
    printf("\n");
    printf("\033[1;34m███╗   ██╗ ███████╗ ██████╗ ██████╗ ██╗   ██╗\033[0m\n");
    printf("\033[1;34m████╗  ██║ ██╔════╝██╔═══██╗██╔══██╗╚██╗ ██╔╝\033[0m\n");
    printf("\033[1;34m██╔██╗ ██║ ███████╗██║   ██║██████╔╝ ╚████╔╝\033[0m\n");
    printf("\033[1;34m██║╚██╗██║ ╚════██║██║   ██║██╔══██╗  ╚██╔╝\033[0m\n");
    printf("\033[1;34m██║ ╚████║ ███████║╚██████╔╝██████╔╝   ██║\033[0m\n");
    printf("\033[1;34m╚═╝  ╚═══╝ ╚══════╝ ╚═════╝ ╚═════╝    ╚═╝\033[0m\n");
    printf("\n");

    printf("\033[36m欢迎使用学生管理系统\n\n");

    printf("用户名:admin \n\n");
    int j = 100,i;
    while (j--) {
        printf("请输入密码 : " );

        // 隐藏密码输入
        int index = 0;
        char ch;
        for(i=0;i<100;i++)
        {
            ch = getch();
            if (ch == 13) // 如果用户按下回车键
                break;
            if (ch == 8 && index > 0) { // 如果用户按下退格键
                putchar('\b');
                putchar(' ');
                putchar('\b');
                index--;
                continue;
            }
            if (ch != 8) { // 忽略退格键
                putchar('*'); // 显示'*'而不是实际输入的字符
                password[index] = ch;
                index++;
            }
        }
        password[index] = '\0'; // 在密码末尾添加null终止符

        if (strcmp(password, predefined_password) == 0) {
            printf("\n**正在登录...\n");
            Sleep(2000);
            printf("\n登录成功!\n");
            return;
        } else {
            printf("\n密码错误,请重试。\n");
        }
    }
    

}

student.h 

#ifndef __STUDENT_H
#define __STUDENT_H

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

#define MAX_PATH 20
#define MAX_SEX 5
#define MAX_major 50
#define MAX_date 100
#define MAX_PASSWORD_LENGTH 50

#define DEFAULT_SZ 3
#define INC_SZ 2

enum Option //学生个人信息
{
	EXIT, //退出--0
	ADD,  //增加--1
	DEL,  //删除--2
    MODIFY, //修改--3
	QUERY,  //查询--4
	OUTPUT,  //输出--5
	SORT,  //排序--6
    SORT_ID, //--7
    Save_score, //--8
    Examine //--9
};

// *****************存放个人学生信息********************
typedef struct
{
    char ID[MAX_PATH];     // 学号
    char name[MAX_PATH];   // 姓名
    char sex[MAX_SEX];    // 性别
    char major[MAX_major]; // 专业
    char grade[MAX_PATH];  // 班级
    char phone[MAX_PATH];  // 电话
} PeoInfo;

//动态的版本
typedef struct Contact
{
	PeoInfo* data;//存放人的信息
	int sz;//记录当前通讯录中实际人的个数
	int capacity;//当前通讯录的容量
}Contact;

// *********************存放学生成绩信息**********************
typedef struct
{
    char ID[MAX_PATH];     // 学号
    char name[MAX_PATH];   // 姓名
    short language; //语文成绩
    short math; //数学成绩
    short English;//英语成绩
    short Total; //三科成绩
    short average;//平均分
}Result;
// 成绩人数
typedef struct Crowd
{
	Result* data;//存放人的信息
	int count;//记录当前通讯录中实际人的个数
	int capacity;//当前通讯录的容量
}Crowd;

//****************************************************
//***************登录界面******************************
void Log_In();

//********************************************************
//***************学生个人信息******************************
void Information();
// 初始化
int InitContact(Contact *pc);
//释放掉内存
void DestroyContact(Contact* pc);
// 增加学生信息
void add_student(Contact *pc);
// 输出学生信息
void output_student(Contact *pc);
//删除学生信息
void delete_student(Contact *pc);
//查询学生信息
void query_student(Contact *pc);
//修改学生信息
void modify_student(Contact *pc);
//排序
void sort_student(Contact *pc);
//保存文件
void save_student(Contact *pc);
//**********************************************************
//**********************************************************
//***************学生成绩管理********************************
//初始化
int InitContact_grade(Crowd *qs);
//增容函数
void CheckCapacity_grade(Crowd* qs);
//释放内存
void Destroy_Crowd(Crowd* pc);
// 增加学生成绩信息
void add_score(Crowd *qs);
//输出学生成绩信息
void output_score(Crowd *qs);
//删除学生成绩信息
void delete_score(Crowd *qs);
//修改学生成绩信息
void modify_score(Crowd *qs);
//查询个人成绩
void query_score(Crowd *qs);
//总分和平均分处理
void All_avse(Crowd *qs,int num);
//根据平均分排序
void sort_avge_score(Crowd *qs);
//根据学号排序
void sort_ID_score(Crowd *qs);
//保存信息到文件
void Save_Score_File(Crowd *qs);
//查看班级平均分
void Class_avge_score(Crowd *qs);

#endif 
  • 12
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值