您现在的位置是:首页 > 正文

C语言详细学生成绩管理系统

2024-04-01 04:28:40阅读 4

欢迎查看我的博客:https://Mr00wang.github.io/

C语言 学生成绩管理系统

简述:该学生管理系统数据结构采用结构体

1、系统需求分析

1.1系统介绍

本学生管理系统是为教师人员提供管理班级成绩的工具,该系统可以实现的对学生的成绩进行增、删、改、查、信息保存和信息导入等基本功能,以及对学生成绩排序和分段的扩展功能,有利于对学生成绩管理。

1.2功能性需求

(1) 成绩录入

(2) 成绩输出、成绩排序(按平均成绩)

(3) 成绩查找

(4) 成绩修改

(5) 删除成绩

(6) 文件存储、文件导入

1.3非功能性需求

(1) 友好的交互页面

(2) 登陆密码设置

(3) 数据的保护

2、程序结构设计

该该系统总体的流程图框架如下

学生成绩管理系统
登 陆 界 面
菜 单 界 面
录入成绩
输出成绩
成绩排序
成绩查找
按学号查找
按姓名查找
成绩修改
成绩删除
按学号删除
按姓名删除
文件管理
文件导入
文件保存

3、用户界面设计

登陆界面

登陆界面根据自己的需要进行设计,尽量设计的和谐美观。
如我的登陆界面额外添加了获取时间和登陆密码功能!
以下展示主要代码和效果展示。

获取时间代码

    time_t timep;    //系统时间 
	struct tm *p_1;
	time (&timep);
	p_1=gmtime(&timep);
	printf("\t\t\t\t\t\t  当前时间%02d时%02d分%\n",8+p_1->tm_hour,p_1->tm_min); 
	printf("\t\t\t\t\t\t   %d年%02d月%02d日\n",1900+p_1->tm_year,1+p_1->tm_mon,p_1->tm_mday);
    printf("\t★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★\n\n");
    printf("\t★\t\t\t\t\t有朋自远方来,不亦乐乎! \t\t\t\t\t★\n\n");
    printf("\t★\t\t\t*****************************************************\t\t\t\t★\n\n");
    printf("\t★\t\t\t\t\t 学 生 管 理 系 统\t\t\t\t\t\t★\n\n");
    printf("\t★\t\t\t  制作者:Mr.Wang 专业:软件工程1801 学号:************\t\t\t\t★\n\n");
    printf("\t★\t\t\t*****************************************************\t\t\t\t★\n\n");
    printf("\t★\t\t\t  欢迎使用软件工程18-01的学生管理系统,祝您使用愉快! \t\t\t\t★\n\n");
    printf("\t★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★\n\n"); 

如图:登陆界面

菜单界面

进入页面后设计一个菜单界面,也就是功能界面,在该界面上进行操作


	 printf("\t\t★————————————————————————————————————————★\n\n");
     printf("\t\t\t   | 1. 成绩录入\t\t2. 成绩显示\t\t3. 各科均分  |\n\n");
     printf("\t\t\t   | 4. 成绩排序\t\t5. 成绩查找\t\t6. 信息修改  |\n\n");
     printf("\t\t\t   | 7. 删除成绩\t\t8. 成绩分段\t\t0. 退出系统  |\n\n");
     printf("\t\t★————————————————————————————————————————★\n");

展示如下:

登陆界面

4、功能设计

在该模块中,将会介绍程序的主要功能实现的设计思想和代码

4.1成绩录入

设计思想

成绩录入是对结构体中班级、姓名、学号和五门成绩的录入,同时加上对五门成绩平均成绩的计算。按照基本的录入,只需用scanf函数对数据输入,用printf函数进行汉字的打印即可。然后进行文件保存该组数据,最后判断是否继续录入。

流程图如下

input

代码

//*************************************
//*************************************
//学生成绩录入
void input(struct Student stu[])
{
    void save(struct Student stu[]);//声明保存文件函数
    int choose;
    int i;
    char tempcla[10]={"-1"};  //定义临时姓名字符串,用于按(-1)返回菜单 
    a:
    system("cls");    //清屏
    fflush(stdin);    //清空缓存区 
    printf("成  绩  录  入\n");
    printf("************************************************************************************************************\n");
    printf("请依次输入\t\t班级、姓名、  学号、     五门课成绩(高数 英语 C语言 计算机基础 软件工程导论)\n");
    printf("班级(按-1返回菜单):");  //输入班级
    while(scanf("%s",stu[count].cla)==0)   //判断返回值,除去类型错误bug 
    {
        fflush(stdin);
        printf("格式有误,请重新输入:");
    }
    if(strcmp(stu[count].cla,tempcla)==0)  //按-1返回菜单
    {
        printf("\n按任意键返回菜单!\n\n");
        system("pause");
        return;
    }
    while(strlen(stu[count].cla)>10)  //判断字符长度
    {
        fflush(stdin);
        printf("班级输入不合理,请重新录入:");
        scanf("%s",stu[count].cla);
    }
    printf("\n姓名:");  //输入姓名
    fflush(stdin);
    while(scanf("%s",stu[count].name)==0)
    {
        fflush(stdin);
        printf("格式有误,请重新输入:");
    }
    while(strlen(stu[count].name)>7)
    {
        fflush(stdin);
        printf("姓名不合理,请重新录入:");
        scanf("%s",stu[count].name);
    }
    printf("\n学号:");    //输入姓名
    w:
    fflush(stdin);
    while(scanf("%lld",&stu[count].num)==0)
    {
        fflush(stdin);
        printf("格式有误,请重新输入:");
    }
    for(i=0;i<count;i++)     //判断重复学号
    {
        if(stu[count].num==stu[i].num)
        {
            printf("已有该学号,请重新输入:\n");
            goto w;
        }
    }
    printf("\n高数(0~100):");  //输入高数
    fflush(stdin);
    while(scanf("%f",&stu[count].score[0])==0)
    {
        fflush(stdin);
        printf("格式有误,请重新输入:");
    }
    while(stu[count].score[0]<0||stu[count].score[0]>100)
    {
        fflush(stdin);
        printf("数据超出,请重新输入:");
        scanf("%f",&stu[count].score[0]);
    }
    printf("\n英语(0~100):");   //输入英语
    fflush(stdin);
    while(scanf("%f",&stu[count].score[1])==0)
    {
        fflush(stdin);
        printf("格式有误,请重新输入:");
    }
    while(stu[count].score[1]<0||stu[count].score[1]>100)
    {
        fflush(stdin);
        printf("数据超出,请重新输入:");
        scanf("%f",&stu[count].score[1]);
    }
    printf("\nC语言(0~100):");  //输入C语言
    fflush(stdin);
    while(scanf("%f",&stu[count].score[2])==0)
    {
        fflush(stdin);
        printf("格式有误,请重新输入:");
    }
    while(stu[count].score[2]<0||stu[count].score[2]>100)
    {
        fflush(stdin);
        printf("数据超出,请重新输入:");
        scanf("%f",&stu[count].score[2]);
    }
    printf("\n计算机基础(0~100):");  //输入计算机基础
    fflush(stdin);
    while(scanf("%f",&stu[count].score[3])==0)
    {
        fflush(stdin);
        printf("格式有误,请重新输入:");
    }
    while(stu[count].score[3]<0||stu[count].score[3]>100)
    {
        fflush(stdin);
        printf("数据超出,请重新输入:");
        scanf("%f",&stu[count].score[3]);
    }
    printf("\n软件工程导论(0~100):"); //输入软件工程导论
    fflush(stdin);
    while(scanf("%f",&stu[count].score[4])==0)
    {
        fflush(stdin);
        printf("格式有误,请重新输入:");
    }
    while(stu[count].score[4]<0||stu[count].score[4]>100)
    {
        fflush(stdin);
        printf("数据超出,请重新输入:");
        scanf("%f",&stu[count].score[4]);
    }
    stu[count].aver=(stu[count].score[0]+stu[count].score[1]+stu[count].score[2]+stu[count].score[3]+stu[count].score[4])/5.0;//计算平均成绩 
    count++;   //结构体数据数+1
    save(p);   //保存文件
    fflush(stdin);
    printf("是否继续录入:\n\n");
    printf("1.是 2.否\n");
    fflush(stdin);
    printf("\n请选择:");
    b:
    while(scanf("%d",&choose)==0)
    {
    	printf("您输入的格式错误,请重新输入:\n");
    	fflush(stdin);
    	goto b;
	}
   switch(choose)
    {
        case 1:goto a;break;
        case 2:return;break;
        default:printf("没有该序号,请重新输入:");goto b;
    }
}

部分代码说明

 while(scanf("%s",stu[count].cla)==0)   //判断返回值,除去类型错误bug 
    {
        fflush(stdin);
        printf("格式有误,请重新输入:");
    }
    
  //在输入成绩时通常直接使用scanf,但当我们做项目时,为了具有一定的容错性,需要判断输入数据的类型和
  //判断scanf的返回值,如果直接使用scanf,输入其它类型的数据,程序将会炸掉,因此我们需要用这种形式
  //保证系统正常运行

scanf的返回值具体解释见他人解释,地址如下:
(https://blog.csdn.net/zhl254467014/article/details/44183567)

为了方便其它功能的实现,在这里需要判断学号是否重复,保证学号的唯一性

 w:
    fflush(stdin);
    while(scanf("%lld",&stu[count].num)==0)
    {
        fflush(stdin);
        printf("格式有误,请重新输入:");
    }
    for(i=0;i<count;i++)     //判断重复学号
    {
        if(stu[count].num==stu[i].num)
        {
            printf("已有该学号,请重新输入:\n");
            goto w;
        }
    }

4.2成绩显示

由于我想按照平均成绩排序的方式输出,因此直接调用该函数

//*************************************
//*************************************
//学生成绩显示
void print(struct Student stu[])
{
    void sort(struct Student stu[]);//声明平均成绩排序函数
    system("cls");//清屏函数
    if(count==0) printf("\n您尚未录入学生信息,请返回菜单进行录入!\n");
    sort(p);    //排序函数
    return;
}

4.3成绩排序

排序思想:
成绩排序是将结构体中的数据按平均成绩进行排序,在本系统中,我将成绩排序非为按五门成绩排序和平均成绩排序,排序的思想是运用冒泡排序。在此功能中需注意的是排序时要将整组数据随着平均成绩一起改变,最后不能出现平均成绩与信息对应不上。其次在进行字符串互换的时候不能直接赋值号进行互换,要用strcpy函数进行复制,在这里只展示按平均成绩排序的代码,其它成绩排序与之相似

//*************************************
//*************************************
//平均成绩排序
void sort(struct Student stu[])
{
    void save(struct Student stu[]);
    system("cls");
    fflush(stdin);
    char tempname[20];  //临时变量
    char tempcla[20];
    int i,j;
    long long int t1;
    float t;
    if(count==0) printf("\n\n您尚未录入学生信息,请返回菜单进行录入!\n\n");
    else
    {
        printf("\n成绩显示(按平均成绩排序)\n");   //冒泡排序
            for(i=0;i<count-1;i++)
            {
                for(j=0;j<count-i-1;j++)
                {
                    if(stu[j].aver<stu[j+1].aver)  //注意字符串的复制 
                    {
                        strcpy(tempcla,stu[j].cla);strcpy(stu[j].cla,stu[j+1].cla);strcpy(stu[j+1].cla,tempcla);
                        strcpy(tempname,stu[j].name);strcpy(stu[j].name,stu[j+1].name);strcpy(stu[j+1].name,tempname);
                        t1=stu[j].num;stu[j].num=stu[j+1].num;stu[j+1].num=t1;
                        t=stu[j].score[0];stu[j].score[0]=stu[j+1].score[0];stu[j+1].score[0]=t;
                        t=stu[j].score[1];stu[j].score[1]=stu[j+1].score[1];stu[j+1].score[1]=t;
                        t=stu[j].score[2];stu[j].score[2]=stu[j+1].score[2];stu[j+1].score[2]=t;
                        t=stu[j].score[3];stu[j].score[3]=stu[j+1].score[3];stu[j+1].score[3]=t;
                        t=stu[j].score[4];stu[j].score[4]=stu[j+1].score[4];stu[j+1].score[4]=t;
                        t=stu[j].aver;stu[j].aver=stu[j+1].aver;stu[j+1].aver=t;

                    }
                }

            }
            printf("************************************************************************************************************\n");
            printf("\t班级\t姓名\t学号\t\t高数\t英语\tC语言\t计算机基础\t软件工程导论\t平均成绩\t\n");
            printf("************************************************************************************************************\n");
            for(i=0;i<count;i++)
                printf("\t%-8s%-8s%-16lld%-8.2lf%-8.2lf%-8.2lf%-16.2lf%-16.2lf%-12.2lf\n",stu[i].cla,stu[i].name,stu[i].num,
                   stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].score[3],stu[i].score[4],stu[i].aver);
    save(p);   //保存文件
    }
    system("pause");
    return;
}

4.4成绩查找

设计思想:
成绩查找需要实现的是按学号和姓名查找到学生的所有信息,然后打印出来。该功能的思想是输入学号或姓名,然后在循环体中对结构体进行遍历,找到所查到的结构体的下标值,然后将该下标值对应学生的信息打印出来。按照姓名查询时,判断字符串是否相等需要用strcmp函数。在循环体中对结构体进行遍历的时候,找到的时候,可以用break跳出循环,提高效率。

流程图如下:

search

代码展示

//*************************************
//*************************************
//按学号查询
void findnum(struct Student stu[])
{
    int i;
    int searchindex=-1;  //定义下表值 
    long long int searchnum;
    fflush(stdin);
    printf("\n请输入查询成绩的学生学号:");
    scanf("%lld",&searchnum);
    for(i=0;i<count;i++)
    {
        if(searchnum==stu[i].num)
        {
            system("cls");
            searchindex=i;
            printf("************************************************************************************************************\n");
            printf("\t班级\t姓名\t学号\t\t高数\t英语\tC语言\t计算机基础\t软件工程导论\t平均成绩\t\n");
            printf("************************************************************************************************************\n");
            printf("\t%-8s%-8s%-16lld%-8.2lf%-8.2lf%-8.2lf%-16.2lf%-16.2lf%-12.2lf\n\n",stu[i].cla,stu[i].name,stu[i].num,
                   stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].score[3],stu[i].score[4],stu[i].aver);
            break;  //找到后跳出 
        }
    }
    if(searchindex==-1)
        printf("\n很抱歉,没有找到该学生的学号!\n\n");
    printf("\n按任意键返回成绩查询\n\n");
    system("pause");
    return;
}
//*************************************
//*************************************
//按姓名查询
void findname(struct Student stu[])
{
    int i;
    char searchname[20];
    int searchindex=-1;
    fflush(stdin);
    printf("\n请输入查询成绩学生的姓名:\n");
    scanf("%s",searchname);
    for(i=0;i<count;i++)  //循环寻找姓名
    {
        if(strcmp(searchname,stu[i].name)==0)
        {
            system("cls");
            searchindex=i;
            printf("************************************************************************************************************\n");
            printf("\t班级\t姓名\t学号\t\t高数\t英语\tC语言\t计算机基础\t软件工程导论\t平均成绩\t\n");
            printf("************************************************************************************************************\n");
            printf("\t%-8s%-8s%-16lld%-8.2lf%-8.2lf%-8.2lf%-16.2lf%-16.2lf%-12.2lf\n\n",stu[i].cla,stu[i].name,stu[i].num,
                   stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].score[3],stu[i].score[4],stu[i].aver);
            break;//找到跳出
        }
    }
    if(searchindex==-1)
        printf("\n很抱歉,没有找到该学生的姓名!\n\n");
    printf("\n按任意键返回成绩查询\n\n");
    system("pause");
    return;
}
//*************************************
//*************************************
//成绩查询
void find(struct Student stu[])
{
    if(count==0)
    {
        printf("\n\n您尚未录入学生信息,请返回菜单进行录入!\n\n");
        system("pause");
        return;
    }
    int choose;
    system("cls");
    fflush(stdin);
    choose:   //成绩查询页面菜单
    printf("\n\t\t\t\t\t\t  成绩查询\n\n");
    printf("\t\t\t\t\t*****************************\n\n");
    printf("\t\t\t\t\t |1.按学号查找 2.按姓名查找|\n\n");
    printf("\t\t\t\t\t |3.全部显示   4.返回菜单  |\n\n");
    printf("\t\t\t\t\t*****************************\n");
    printf("\t\t\t\t\t\n请输入查询方式:");
    a:
    while(scanf("%d",&choose)==0)
    {
        printf("输入格式有误,请您重新输入:");
        fflush(stdin);
    }
    switch(choose)
    {
	    case 1:
	        findnum(p);
	        system("cls");
	        goto choose;
	        break;
	    case 2:
	        findname(p);
	        system("cls");
	        goto choose;
	        break;
	    case 3:
	        print(p);
	        system("cls");
	        goto choose;
	        break;
	    case 4:
	        printf("\n按任意键返回菜单!\n\n");
	        system("pause");
	        return;
	    default:
	        printf("没有该序号,请您重新输入:");goto a;
    }
}

4.5成绩修改

该功能与录入成绩功能相似,成绩修改是对结构体中的信息进行修改,首先找到需要修改同学结构体的下标值,然后对该下标值对应的信息进行覆盖修改,该信息修改的录入与成绩录入功能的录入相同,同样需要注意与成绩录入时的漏洞。过多的不说了,直接上代码,依据我的需求,代码较多,仅供参考

******************************
//修改成绩
void change(struct Student stu[])
{
    void save(struct Student stu[]);
    int i,j;
    int choose;
    long long int searchnum,tempnum;
    int searchindex=-1;
    if(count==0)
    {
        printf("\n\n您尚未录入学生信息,请返回菜单进行录入!\n\n");
        system("pause");
        return;
    }
    a:
    system("cls");
    printf("\n修改成绩!\n\n");
    fflush(stdin);
    printf("************************************************\n");
    printf("\n请输入修改学生的学号:(按-1返回菜单)");
    scanf("%lld",&searchnum);
    fflush(stdin);
    if(searchnum==-1)
    {
        printf("\n按任意键返回菜单!\n\n");
        system("pause");
        return;
    }
    system("cls");
    for(i=0;i<count;i++)
    {
        if(searchnum==stu[i].num)
        {
            searchindex=i;
            printf("\n该学生信息:\n");  //修改成绩页面菜单
            printf("************************************************************************************************************\n");
            printf("\t班级\t姓名\t学号\t\t高数\t英语\tC语言\t计算机基础\t软件工程导论\t平均成绩\t\n");
            printf("************************************************************************************************************\n");
            printf("\t%-8s%-8s%-16lld%-8.2lf%-8.2lf%-8.2lf%-16.2lf%-16.2lf%-12.2lf\n\n",stu[i].cla,stu[i].name,stu[i].num,
                   stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].score[3],stu[i].score[4],stu[i].aver);
            printf("************************************************\n");
            printf("|1.修改班级\t       2. 修改姓名            |\n");
            printf("|3.修改学号\t       4. 修改高数            |\n");
            printf("|5.修改英语\t       6. 修改C语言           |\n");
            printf("|7.修改计算机基础      8. 修改软件工程导论    |\n");
            printf("|9.返回菜单\t                              |\n");
            printf("************************************************\n");
            printf("请选择修改的信息:");
            choose:
            while(scanf("%d",&choose)==0)
            {
                printf("输入格式有误,请您重新输入:");
                fflush(stdin);
            }
            switch(choose)
            {
	            case 1:
	                fflush(stdin);
	                printf("请修改班级:");
	                while(scanf("%s",stu[i].cla)==0)
	                {
	                    printf("格式有误,请重新输入:");
	                    fflush(stdin);
	                }
	                while(strlen(stu[count].cla)>10)  //判断字符长度
	                {
	                    printf("班级输入不合理,请重新录入:");
	                    fflush(stdin);
	                    scanf("%s",stu[count].cla);
	                }
	                break;
	            case 2:
	                fflush(stdin);
	                printf("请修改姓名:");
	                while(scanf("%s",stu[i].name)==0)
	                {
	                    printf("格式有误,请重新输入:");
	                    fflush(stdin);
	                }
	                while(strlen(stu[count].name)>10)  //判断字符长度
	                {
	                    printf("班级输入不合理,请重新录入:");
	                    fflush(stdin);
	                    scanf("%s",stu[count].name);
	                }
	                break;
	            case 3:
	                fflush(stdin);
	                printf("请修改学号:");
	                w:
	                while(scanf("%lld",&stu[i].num)==0)
	                {
	                    printf("格式有误,请重新输入:");
	                    fflush(stdin);
	                }
	                tempnum=stu[i].num;
	                stu[i].num=0;
	                for(j=0;j<count;j++)
	                {
	                    if(tempnum==stu[j].num)
	                    {
	                        printf("已有该学号,请重新输入:\n");
	                        goto w;
	                    }
	                }
	                stu[i].num=tempnum;
	                break;
	            case 4:
	                fflush(stdin);
	                printf("请修改高数:");
	                while(scanf("%f",&stu[i].score[0])==0)
	                {
	                    printf("格式有误,请重新输入:");
	                    fflush(stdin);
	                }
	                while(stu[i].score[0]<0||stu[i].score[0]>100)
	                {
	                    printf("格式有误,请重新输入:");
	                    fflush(stdin);
	                    scanf("%f",&stu[i].score[0]);
	                }
	                break;
	            case 5:
	                fflush(stdin);
	                printf("请修改英语:");
	                while(scanf("%f",&stu[i].score[1])==0)
	                {
	                    printf("格式有误,请重新输入:");
	                    fflush(stdin);
	                }
	                while(stu[i].score[1]<0||stu[i].score[1]>100)
	                {
	                    printf("格式有误,请重新输入:");
	                    fflush(stdin);
	                    scanf("%f",&stu[i].score[1]);
	                }
	                break;
	            case 6:
	                fflush(stdin);
	                printf("请修改C语言:");
	                while(scanf("%f",&stu[i].score[2])==0)
	                {
	                    printf("格式有误,请重新输入:");
	                    fflush(stdin);
	                }
	                while(stu[i].score[2]<0||stu[i].score[2]>100)
	                {
	                    printf("格式有误,请重新输入:");
	                    fflush(stdin);
	                    scanf("%f",&stu[i].score[2]);
	                }
	                break;
	            case 7:
	                fflush(stdin);
	                printf("请修改计算机基础:");
	                while(scanf("%f",&stu[i].score[3])==0)
	                {
	                    printf("格式有误,请重新输入:");
	                    fflush(stdin);
	                }
	                while(stu[i].score[3]<0||stu[i].score[3]>100)
	                {
	                    printf("格式有误,请重新输入:");
	                    fflush(stdin);
	                    scanf("%f",&stu[i].score[3]);
	                }
	                break;
	            case 8:
	                fflush(stdin);
	                printf("请修改软件工程导论:");
	                while(scanf("%f",&stu[i].score[4])==0)
	                {
	                    printf("格式有误,请重新输入:");
	                    fflush(stdin);
	                }
	                while(stu[i].score[4]<0||stu[i].score[4]>100)
	                {
	                    printf("格式有误,请重新输入:");
	                    fflush(stdin);
	                    scanf("%f",&stu[i].score[4]);
	                }
	                break;
	            case 9:
	                printf("\n按任意键返回菜单!\n\n");
	                save(p);
	                return;
	            default:
	                printf("没有该序号,请您重新输入:");
	                goto choose;
            }//switch结尾处 
            stu[i].aver=(stu[i].score[0]+stu[i].score[1]+stu[i].score[2]+stu[i].score[3]+stu[i].score[4])/5.0;
            printf("\n修改成功:\n");
            printf("************************************************************************************************************\n");
            printf("\t班级\t姓名\t学号\t\t高数\t英语\tC语言\t计算机基础\t软件工程导论\t平均成绩\t\n");
            printf("************************************************************************************************************\n");
            printf("\t%-8s%-8s%-16lld%-8.2lf%-8.2lf%-8.2lf%-16.2lf%-16.2lf%-12.2lf\n\n",stu[i].cla,stu[i].name,stu[i].num,
                   stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].score[3],stu[i].score[4],stu[i].aver);
        }//if结束处
    }//for结束处
    if(searchindex==-1)
    {
        printf("\n很抱歉,未能找到该学生,请重新输入学号!\n\n");
        system("pause");
        goto a;
    }
    save(p);
    system("pause");
    return;
}

4.6成绩删除

设计思想:
删除成绩是对结构体中的信息进行删除,其实对于C语言无法进行删除本身的意义,只是做出了一些假像,其实删除成绩就是覆盖成绩。删除成绩分为按学号删除和按姓名删除。删除成绩的思想为覆盖,首先通过结构体的遍历找到所删学生信息的下标值,然
后从该下标值开始,后面一个学生信息覆盖前面一个学生的信息,最后最关键的一点是将全局变量count即结构体组数-1

流程图如下:

delete

代码如下:

//*************************************
//*************************************
//删除成绩
void del(struct Student stu[])
{
    void delnum(struct Student stu[]);
    void delname(struct Student stu[]);
    void save(struct Student stu[]);
    int choose;
    if(count==0)
    {
        printf("\n\n您尚未录入学生信息,请返回菜单进行录入!\n\n");
        system("pause");
        return;
    }
    choose:
    fflush(stdin);   //删除成绩页面菜单
    printf("\n\t\t\t\t\t     删除成绩\n\n");
    printf("\t\t\t\t********************************\n\n");
    printf(" \t\t\t\t\t   1.按学号删除\n\n\t\t\t\t\t   2.按姓名删除\n\n\t\t\t\t\t   3.返回菜单\n\n");
    printf("\t\t\t\t********************************\n\n");
    printf("请输入删除方式:");
    a:
    while(scanf("%d",&choose)==0)
    {
        printf("输入格式有误,请您重新输入:");
        fflush(stdin);
    }
    switch(choose)
    {
	    case 1:
	        delnum(p);
	        save(p);
	        system("cls");
	        goto choose;
	        break;
	    case 2:
	        delname(p);
	        save(p);
	        system("cls");
	        goto choose;
	        break;
	    case 3:
	        printf("\n按任意键返回菜单!\n\n");
	        system("pause");
	        return;
	    default:
	        printf("没有该序号,请您重新输入:");goto a;
    }

}
//*************************************
//*************************************
//按学号删除成绩
void delnum(struct Student stu[])
{
    void print(struct Student stu[]);
    int i,choose;
    int searchindex=-1;
    long long int deletenum;
    fflush(stdin);
    printf("请输入要删除学生的学号(按-1返回):");
    scanf("%lld",&deletenum);
    printf("是否确定删除:\n");
    fflush(stdin);
    printf("1.是 2.否\n");
    fflush(stdin);
    printf("请选择:");
    b:
    while(scanf("%d",&choose)==0)
    {
    	printf("您输入的格式错误,请重新输入:\n");
    	fflush(stdin);
    	goto b;
	}
    switch(choose)
    {
        case 1:break;
        case 2:return;break;
        default:printf("没有该序号,请重新输入:");goto b;
    }
    if(deletenum==-1)
    {
        printf("\n按任意键返回删除成绩!\n\n");
        system("pause");
        return;
    }
    for(i=0;i<count;i++)
    {
        if(deletenum==stu[i].num)
        {
            searchindex=i;
            break;
        }
    }
    if(searchindex==-1)
    {
        printf("\n很遗憾,未能找到所要删除学生的学号!\n");
        printf("\n按任意键返回菜单\n\n");
        system("pause");
        return;
    }
    else  //查找信息后,每组数据往前进行覆盖
    {
        for(i=searchindex;i<count-1;i++)
        {
            strcpy(stu[i].cla,stu[i+1].cla);
            stu[i].num=stu[i+1].num;
            strcpy(stu[i].name,stu[i+1].name);
            stu[i].score[0]=stu[i+1].score[0];
            stu[i].score[1]=stu[i+1].score[1];
            stu[i].score[2]=stu[i+1].score[2];
            stu[i].score[3]=stu[i+1].score[3];
            stu[i].score[4]=stu[i+1].score[4];
            stu[i].aver=stu[i+1].aver;
        }
        count--;  //总数据组-1
    }
    if(count==0)
    {
        printf("\n目前没有学生信息,请返回菜单录入!\n\n");
        system("pause");
        return;
    }
    system("cls");  //删除后进行打印
    printf("\n删除成功!\n\n");
    printf("************************************************************************************************************\n");
    printf("\t班级\t姓名\t学号\t\t高数\t英语\tC语言\t计算机基础\t软件工程导论\t平均成绩\t\n");
    printf("************************************************************************************************************\n");
    for(i=0;i<count;i++)
         printf("\t%-8s%-8s%-16lld%-8.2lf%-8.2lf%-8.2lf%-16.2lf%-16.2lf%-12.2lf\n",stu[i].cla,stu[i].name,stu[i].num,
                   stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].score[3],stu[i].score[4],stu[i].aver);
    printf("\n按任意键返回菜单\n\n");
    system("pause");
    return;
}
//*************************************
//*************************************
//按姓名删除成绩
void delname(struct Student stu[])
{
    void print(struct Student stu[]);
    int i,choose;
    char tempname[10]={"-1"};
    int searchindex=-1;
    char deletename[20];
    fflush(stdin);
    printf("请输入要删除学生的姓名(按-1返回):");
    scanf("%s",deletename);
    printf("是否确定删除:\n");
    fflush(stdin);
    printf("1.是 2.否\n");
    fflush(stdin);
    printf("请选择:");
    b:
    while(scanf("%d",&choose)==0)
    {
    	printf("您输入的格式错误,请重新输入:\n");
    	fflush(stdin);
    	goto b;
	}
	switch(choose)
    {
        case 1:;break;
        case 2:return;break;
        default:printf("没有该序号,请重新输入:");goto b;
    }
    if(strcmp(deletename,tempname)==0)
    {
        printf("\n按任意键返回删除成绩!\n\n");
        system("pause");
        return;
    }
    for(i=0;i<count;i++)
    {
        if(strcmp(deletename,stu[i].name)==0)
        {
            searchindex=i;
            break;
        }
    }
    if(searchindex==-1)
    {
        printf("\n很遗憾,未能找到所要删除学生的姓名!\n");
        printf("\n按任意键返回菜单\n\n");
        system("pause");
        return;
    }
    else
    {
        for(i=searchindex;i<count-1;i++)
        {
            strcpy(stu[i].cla,stu[i+1].cla);
            stu[i].num=stu[i+1].num;
            strcpy(stu[i].name,stu[i+1].name);
            stu[i].score[0]=stu[i+1].score[0];
            stu[i].score[1]=stu[i+1].score[1];
            stu[i].score[2]=stu[i+1].score[2];
            stu[i].score[3]=stu[i+1].score[3];
            stu[i].score[4]=stu[i+1].score[4];
            stu[i].aver=stu[i+1].aver;
        }
        count--;
    }
    printf("\n");
    printf("\n删除成功!\n\n");
    if(count==0)
    {
        printf("\n目前没有学生信息,请返回菜单录入!\n\n");
        system("pause");
        return;
    }
    system("cls");
    printf("\n删除成功!\n\n");
    printf("************************************************************************************************************\n");
    printf("\t班级\t姓名\t学号\t\t高数\t英语\tC语言\t计算机基础\t软件工程导论\t平均成绩\t\n");
    printf("************************************************************************************************************\n");
    for(i=0;i<count;i++)
        printf("\t%-8s%-8s%-16lld%-8.2lf%-8.2lf%-8.2lf%-16.2lf%-16.2lf%-12.2lf\n",stu[i].cla,stu[i].name,stu[i].num,
                   stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].score[3],stu[i].score[4],stu[i].aver);
    printf("\n按任意键返回菜单\n\n");
    system("pause");
    return;
}

核心代码如下,请好好理解

for(i=0;i<count;i++){
    if(deletenum==stu[i].num)
     {
          searchindex=i;
          break;
      }
 }
  //查找信息后,每组数据往前进行覆盖
 for(i=searchindex;i<count-1;i++)
  {
         strcpy(stu[i].cla,stu[i+1].cla);
         stu[i].num=stu[i+1].num;
         strcpy(stu[i].name,stu[i+1].name);
         stu[i].score[0]=stu[i+1].score[0];
         stu[i].score[1]=stu[i+1].score[1];
         stu[i].score[2]=stu[i+1].score[2];
         stu[i].score[3]=stu[i+1].score[3];
         stu[i].score[4]=stu[i+1].score[4];
         stu[i].aver=stu[i+1].aver;
    }
    count--;  //总数据组数-1

4.7文件保存

文件存储简要介绍:

文件存储是将程序中的数据存储如磁盘中,生成文件。在我们没有进行保存之前,我们每次进入系统都要进行录入,如果数据很多,那么操作十分复杂。所有我们需要对数据进行存储。然后进入系统时进行导入,文件的存储分为两种方法,一种是十进制进行存储,另一种是二进制进行存储。这两种方式都可以对数据进行存储,但每种方式都有其的优点和缺点,对于第一种十进制存储,用fprintf函数对磁盘写入,它的优点是格式化输出,在磁盘中可查看数据,也可进行修改使用方便,容易理解,缺点是由于在输入时要将文件中的ASCII码转换为二进制形式在保存在内存变量中,在输出时又要将内存的二进制形式转换成字符,要花费较多时间。并且数据可被其他人查看和修改,在保存数据时需要进行进制转换,可能会造成数据错误。对于二进制存储,用fwrite函数对磁盘文件进行写,优点是fwrite函数可向文件写一个数据块,在读写时以二进制形式进行的。在向磁盘写数据时,直接将内存中一组数据原封不动、不加转换地复制到磁盘文件上,不需要进制转换,运行速度高。其缺点是生成二进制文件,信息是一堆乱码,但是该文件安全系数高,他人无法查看文件内容,对文件数据进行保护。

我的文件是使用二进制存储
具体代码如下:

void save(struct Student stu[])
{
    int i;
    FILE*fp;
    fp=fopen("student.bat","wb");
    for(i = 0; i < count; i++)
    {
        if(fwrite(&stu[i],sizeof(struct Student),1,fp)!=1)
            printf("file write error\n");
    }
    fclose(fp);
    printf("\n已保存至文件中\n\n");
}

鉴于有些人使用十进制文件,我这里也写了,代码如下:

FILE *fp;
int i;
if((fp=fopen("student.txt","w"))==NULL)
{
	 printf("error");
	exit(0);
}
for(i = 0; i < count; i++)
fprintf(fp,"\t%-8s%-8s%-16lld%-8.2lf%-8.2lf%-8.2lf%-16.2lf%-16.2lf%-12.2lf\n",stu[i].cla,stu[i].name,stu[i].num,stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].score[3],stu[i].score[4],stu[i].aver);
printf("save success!\n");
fclose(fp);

4.7文件保存

简要概述
文件导入是对磁盘中的数据导入进学生管理系统的结构体中,对数据进行使用。文件导入是与文件存储相对应,十进制导入对应十进制存储,二进制导入对应二进制存储。因此文件导入也分为两种,十进制导入用fscanf,二进制文件导入用fread

这里同样展示两种方式
首先是二进制

//文件导入
void read(struct Student stu[])
{
    int i;
    FILE*fp;
    if((fp=fopen("student.bat","rb"))==NULL)
        return;
    for(i=0;i<1000;i++)
    {
        if(fread(&stu[i],sizeof(struct Student),1,fp)!=1)
        {
            if(feof(fp))
            {
                fclose(fp);
                goto a;
            }
            printf("file read error\n");
        }
        count++;  //存入一个,数据组数+1
    }
    fclose(fp);
    a:
    printf("\n导入文件已成功,祝您使用愉快!\n\n");
    printf("请按任意键进入页面菜单!\n\n");
    system("pause");
    return;
}

二进制形式

while(num!=EOF){
		   num=fscanf(fp,"%s %s %lld %f %f %f %f %f %f\n",stu[i].cla,stu[i].name,stu[i].num,
                 stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].score[3],stu[i].score[4],stu[i].aver);
		    count++;  //存入一个,数据组数+1
}
	count--;

4.8主函数代码

主函数代码展示

//*************************************
//*************************************
//主函数
int main()
{
    system("color 9E"); //设置背景颜色
    int i=4;
    char code[20]={'1','2','3','4','5','6'},password[20];
	int x;
	char c;
    //初始页面
    time_t timep;    //系统时间 
	struct tm *p_1;
	time (&timep);
	p_1=gmtime(&timep);
	printf("\t\t\t\t\t\t  当前时间%02d时%02d分%\n",8+p_1->tm_hour,p_1->tm_min); 
	printf("\t\t\t\t\t\t   %d年%02d月%02d日\n",1900+p_1->tm_year,1+p_1->tm_mon,p_1->tm_mday);
    printf("\t★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★\n\n");
    printf("\t★\t\t\t\t\t有朋自远方来,不亦乐乎! \t\t\t\t\t★\n\n");
    printf("\t★\t\t\t*****************************************************\t\t\t\t★\n\n");
    printf("\t★\t\t\t\t\t 学 生 管 理 系 统\t\t\t\t\t\t★\n\n");
    printf("\t★\t\t\t  制作者:Mr.Wang 专业:软件工程1801 学号:************\t\t\t\t★\n\n");
    printf("\t★\t\t\t*****************************************************\t\t\t\t★\n\n");
    printf("\t★\t\t\t  欢迎使用软件工程18-01的学生管理系统,祝您使用愉快! \t\t\t\t★\n\n");
    printf("\t★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★\n\n"); 
	printf("请输入六位登陆密码!\n");
	q:
	x=0;
	while(x<6 && c!=13)
	{
		c=getch();
		if(c!=13)
		putchar('*');
		password[x++]=c;
	}
	password[x]='\0';
    if(strcmp(password,code)!=0)
    {
    	fflush(stdin);
        printf("\n输入密码有误,您还有%d次机会,请重新输入:",i--);
        if(i==-1)
        {
            exit(0);
        }
        goto q;
    }
    read(p); //导入文件
    system("cls");    //清屏
    //页面菜单
    menu:
    system("cls");
    time (&timep);
	p_1=gmtime(&timep);
    printf("\t\t\t\t\t\t   当前时间%02d时%02d分%\n",8+p_1->tm_hour,p_1->tm_min); 
	printf("\t\t\t\t\t\t    %d年%02d月%02d日\n",1900+p_1->tm_year,1+p_1->tm_mon,p_1->tm_mday);
    printf("\n");
    printf("\t\t\t\t\t\t    页  面  菜  单\n");
    printf("\n");
    printf("\t\t★————————————————————————————————————————★\n\n");
    printf("\t\t\t   | 1. 成绩录入\t\t2. 成绩显示\t\t3. 各科均分  |\n\n");
    printf("\t\t\t   | 4. 成绩排序\t\t5. 成绩查找\t\t6. 信息修改  |\n\n");
    printf("\t\t\t   | 7. 删除成绩\t\t8. 成绩分段\t\t0. 退出系统  |\n\n");
    printf("\t\t★————————————————————————————————————————★\n");
    printf("\t\t\t\t\t\t          * \n");
    printf("\t\t\t\t\t\t         *** \n");
    printf("\t\t\t\t\t\t        ***** \n");
    printf("\t\t\t\t\t\t       *******\n");
    printf("\t\t\t\t\t\t      *********\n");
    printf("\t\t\t\t\t\t     *********** \n");
    printf("\t\t\t\t\t\t ********************\n");
    printf("\t\t\t\t\t\t  ******************\n");
    printf("\t\t\t\t\t\t   ******* ********\n");
    printf("\t\t\t\t\t\t  *******   ********\n");
    printf("\t\t\t\t\t\t ******       *******\n");
    printf("\t\t\t\t\t\t******          ******\n");
    printf("请选择相应序号:");
    int choose;
    int a; 
    w:
    while(scanf("%d",&choose)==0)
    {
        printf("格式错误,请重新输入:");
        fflush(stdin);
    }
    switch(choose)
    {
    	case 1:   //成绩录入
	        system("cls");
	        printf("学生成绩录入\n");
	        input(p);
	        goto menu;
	    case 2:  //成绩显示和排序
	    	system("cls");
	        printf("学生成绩显示\n");
	        print(p);
	        goto menu;
	    case 3:  //均科成绩 
	    	system("cls");
			average(p);
			goto menu;
	    case 4:  //成绩排序
	    	 system("cls");
	        projectsort(p);
	        goto menu;
	    case 5:  //成绩查找
	        system("cls");
	        find(p);
	        goto menu;
	    case 6:  //成绩修改
		    system("cls");
	        change(p);
	        goto menu;
	    case 7:  //成绩删除
		    system("cls");
	        del(p);
	        goto menu;
	    case 8:  //成绩分段
		    system("cls");
	        section(p);
	        goto menu;
	    case 0: //退出系统
	        fflush(stdin);
	        printf("\n是否继续退出:\n");
	        printf("\n1. 是 2. 否\n\n");
	        back:
	        printf("请选择:");
	        while(scanf("%d",&a)==0)
	        {
	        	fflush(stdin);
	        	printf("您输入格式有误,请重新输入:");
			}
	        if(a==1)
	        {
	            system("cls");
	            //心形图案 
	            float y, x, b;
	            for (y = 1.5f;y > -1.5f;y -= 0.1f)
	            {
	                for (x = -1.5f;x < 1.5f;x += 0.05f)
	                {
	                    b = x*x + y*y - 1;
	                    putchar(b*b*b - x*x*y*y*y <= 0.0f ? '*' : ' ');
	                }
	                putchar('\n');
	            }
	            Sleep(1000);  //休眠 
	            printf("欢迎下次继续使用本产品!\n");
	            printf("正在退出,请稍后.");
	            Sleep(500);
	            printf(".");
	            Sleep(500);
	            printf(".");
	            Sleep(500);
	            printf(".");
	            Sleep(500);
	            printf(".");
	            Sleep(500);
	            printf(".");
	            Sleep(500);
	            exit(0);
	        }//if(a==1)结束处 
	        if(a==2)goto menu;
	        if(a!=1||a!=2)printf("输入有误,重新输入:\n");goto back;
	    default:
	    	printf("没有该序号!请重新输入:");
        	goto w;
	}//switch结束处 
    return 0;
}

4、效果展示

login
inputprintfsortchangeexit

退出时的效果可以自行添加,这里我在csdn上找的时一个心型图案,该图案设计者链接如下:

(https://blog.csdn.net/stone15165/article/details/80260580)

源码在github上:https://github.com/Mr00wang/C-language.git
以上是该学生管理系统的全部内容,上面没有对各科均分和成绩分段进行展述,如有问题请留言,谢谢!

网站文章

  • 【错误记录】TabLayout 升级支持库版本后报错 ( support:design 支持库升级到 28.0.0 后源码发生变更 )

    【错误记录】TabLayout 升级支持库版本后报错 ( support:design 支持库升级到 28.0.0 后源码发生变更 )

    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method &#39;void java.lang.reflect.Field.setAccessible(boolean)&#39; on a null object reference

    2024-04-01 04:28:33
  • 虚拟机NAT 有线被拔出 eth0卡消失

    宿主机VMware DHCP 和VMware NAT 服务没开

    2024-04-01 04:27:54
  • contains函数

    CONTAINS 函数CONTAINS 是字符串处理函数,它能够处理所有字符串数据类型(BIT、BLOB 和 CHARACTER),并返回布尔值以指示一个字符串是否包含在另一个字符串中。示例: St...

    2024-04-01 04:27:47
  • opc怎么在计算机上测试,Matrikon OPC UA Tunneller使用教程:如何执行回送测试?

    opc怎么在计算机上测试,Matrikon OPC UA Tunneller使用教程:如何执行回送测试?

    Matrikon OPC UA Tunneller使用教程:如何执行回送测试?Matrikon OPC UA Tunneller在未来可以帮助您对基础设施的控制,达到提高 OPC UA的利用率的预期。...

    2024-04-01 04:27:39
  • 一篇文章告诉你如何入门网络安全行业

    一篇文章告诉你如何入门网络安全行业

    Hello!大家好!欢迎来到网络安全情报局,最近收到很多小伙伴的私信,对黑客技术很感兴趣,但是不知道如何着手学习,今天就为大家带来详细的解答。如果觉得对你有用记得点赞分享哦!​话不多说,直接进入正文0...

    2024-04-01 04:26:57
  • java 乱码 spring filter_解决SpringMVC的乱码问题:CharacterEncodingFilter

    在使用 SpringMVC 框架的过程中,如果前台有包含中文的请求,或者后台有包含中文的响应,有可能会出现乱码的情况。在以前的 Servlet 中,我们使用 request.setCharacterE...

    2024-04-01 04:26:50
  • ubuntu18.04安装Anaconda3_2022通用

    ubuntu18.04安装Anaconda3_2022通用

    Anaconda的安装

    2024-04-01 04:26:43
  • RabbitMQ 消息队列之 Exchange Types

    写在前面RabbitMQ遵循AMQP 0-9-1协议 AMQP 0-9-1协议简介消息发布到交换站,这通常被比作邮局或邮箱。然后交换器使用称为绑定的规则将消息副本分发到队列。然后,AMQP代理将消息传递给订阅队列的消费者,或者根据需要从队列中获取消息。发布消息时,发布者可以指定各种消息属性(消息元数据)。这些元数据中的一些可能由代理使用,但是,其他部分对代理完全不透明,仅供接收消息的应用...

    2024-04-01 04:26:36
  • c++动态规划典型案例

    动态规划 动态规划的三要素 重叠子问题、最优子结构、状态转移方程 明确「状态」 -&gt; 定义 dp 数组/函数的含义 -&gt; 明确「选择」-&gt; 明确 base case。 第⼆个凑零钱的...

    2024-04-01 04:25:53
  • 单向链表的实现--查询

    单向链表的实现--查询

    前一讲讲到的链表创建和插入,这里我们直接使用前面的程序功能来辅助实现链表的数据查询。 功能:根据指定的 ISBN 或书名查找相应图书的有关信息, 并返回该图书在表中的位置序号。 singLinkList.h头文件内容声明和定义:...............

    2024-04-01 04:25:46