学生管理系统(初级)

    #include <stdio.h>
    #include <stdlib.h>
    #include<string.h>
    #define Size sizeof(struct Student)
    struct Student *p = NULL;//接收返回的头指针
    typedef struct Student
    {
        int grade;
        long student_number;//学号
        char name[20];//姓名
        char course[20];//课程名
        float usual_score;//平时成绩
        float test_score;//考试成绩
        float total_score;//总评成绩
        struct Student *next;
    } S;
    void print_char()//打印******** 分隔程序块
    {
        printf("********************************************************************************\n");
    }
    void print_menu()//打印功能模块
    {
        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、查询班级优秀率\n");
        printf("11、查询课程最高分,最低分\n");
        printf("12、输出文件学生信息\n");
        printf("13、退出系统\n");
    }
    void print(S *head)//输出所有结点信息
    {
        printf("所有信息如下:\n");
        printf("班级 \t 学号\t 姓名\t         科目         平时成绩      考试成绩    总成绩\n");
        S *ptr = head;
        while( ptr  != NULL)
        {
            printf("%d\t%ld\t%-10s       %-10s    %.2f         %.2f       %.2f\n",ptr->grade,ptr->student_number,ptr->name,ptr->course,ptr->usual_score,ptr->test_score,ptr->total_score);
            ptr = ptr->next;
        }
    }
    S *creat_file()//从文件读取学生信息
    {
        void print();
        unsigned n;
        S *head,*node,*end;
        FILE *fp;   //定义文件指针fp
        if((fp = fopen("date_students.txt","r")) == NULL)//打开输出文件并使fp指向此文件 r :读取文件
        {
            printf("connot open the file\n");
            exit(0);
        }
        fscanf(fp,"%d",&n);
        printf("文件学生信息:\n");
        head = (S*)malloc(Size);//head 创建第一个结点
        fscanf(fp,"%d%ld%s%s%f%f",&head->grade,&head->student_number,head->name,head->course,&head->usual_score,&head->test_score);//为第一个结点赋值
        head->total_score = head->usual_score*0.2 + head->test_score*0.8;//总评成绩
        end = head;
        for(int i = 2; i <= n; i++)
        {
            node = (S*)malloc(Size);
            end->next = node;
            end = node;
            fscanf(fp,"%d%ld%s%s%f%f",&node->grade,&node->student_number,node->name,node->course,&node->usual_score,&node->test_score);//为下一个个结点赋值
            node->total_score =node->usual_score*0.2 +node->test_score*0.8;//总评成绩
        }
        end->next = NULL;
        //print( head);
        return head;
    }
    S *creat()//创建n个结点输入学生信息并将信息输出到文件T_date
    {
        void print();
        FILE *fp;
        unsigned n;
        if((fp = fopen("T_date.txt","w")) == NULL)//创建一个用于写入的文本文件
        {
            printf("connot open the file\n");
            exit(0);
        }
        printf("有多少组学生数据:\n");
        // while(scanf("%u",&n)!=EOF)
        scanf("%u",&n);
        if(n == 0)
            exit(0);
        printf("请依次输入%d组数据:",n);
        printf("班级  学号  姓名   科目  平时成绩  考试成绩\n");
        fprintf(fp,"班级  学号  姓名   科目  平时成绩  考试成绩\n");
        S *head,*node,*end;
        head = (S*)malloc(Size);//head 创建第一个结点
        scanf("%d%ld%s%s%f%f",&head->grade,&head->student_number,head->name,head->course,&head->usual_score,&head->test_score);//为第一个结点赋值
        head->total_score = head->usual_score*0.2 + head->test_score*0.8;//总评成绩
        fprintf(fp,"%d\t%ld\t%-10s       %-10s    %.2f         %.2f       %.2f\n",head->grade,head->student_number,head->name,head->course,head->usual_score,head->test_score,head->total_score);
        end = head;
        for(int i = 2; i <= n; i++)
        {
            node = (S*)malloc(Size);
            end->next = node;
            end = node;
            scanf("%d%ld%s%s%f%f",&node->grade,&node->student_number,node->name,node->course,&node->usual_score,&node->test_score);//为下一个个结点赋值
            node->total_score =node->usual_score*0.2 +node->test_score*0.8;//总评成绩
            fprintf(fp,"%d\t%ld\t%-10s       %-10s    %.2f         %.2f       %.2f\n",node->grade,node->student_number,node->name,node->course,node->usual_score,node->test_score,node->total_score);
        }
        end->next = NULL;
        fclose(fp);
        return head;
    }
    S* change(S *head)// 修改 结点学生信息
    {
        int i = 1,n = 0;
        S *t = head;
        printf("修改第几个学生的信息\n");
        scanf("%d",&n);
        while(i < n && t != NULL )
        {
            t = t->next;
            i++;
        }
        if(n != 0 && t != NULL)
        {
            printf("请输入要修改学生的信息:\n");
            scanf("%d%ld%s%s%f%f",&t->grade,&t->student_number,t->name,t->course,&t->usual_score,&t->test_score);//为修改的结点赋值
            t->total_score =t->usual_score*0.2 +t->test_score*0.8;//总评成绩
            //  printf("修改后的数据:\n");
            // print(p);//改变之后输出
        }
        else
            puts("结点不存在!\n");
        return head;
    }
    S * delet(S *head)// 删除 结点学生信息
    {
        int i = 1,n = 0;
        printf("删除第几个学生信息:\n");
        scanf("%d",&n);
        S* t = head, *in;
        if(n == 1)//判断是否为第一个结点
        {
            in  = t;
            head  = head->next;
            free(in);//函数释放指针in指向的空间,以供以后使用。
        }
        else
        {
            while (i < n && t != NULL)
            {
                in = t;
                t = t->next;
                i++;
            }
            if (n != 0 && n != 1&& t != NULL)
            {
                in->next = t->next;
                free(t);//功能: 函数释放指针t指向的空间,以供以后使用。
            }
            else
            {
                puts("结点不存在");
            }
        }
        return head;
    }
    void serch_number(S *head)// 学号 查找学生信息
    {
        long student_number;
        int  flag = 1,i = 1;
        printf("请输入需要查询的学号:\n");
        scanf("%ld",&student_number);
        S *t = head;
        while(t != NULL)
        {
            while(t != NULL  &&  t->student_number != student_number   )
                t = t->next;
            if(t != NULL)
            {
                if(i)
                {
                    printf("班级 \t 学号\t 姓名\t         科目         平时成绩      考试成绩    总成绩\n");//有信息输出时 只输出一次
                    i = 0;
                }
                printf("%d\t%ld\t%-10s       %-10s    %.2f         %.2f       %.2f\n",t->grade,t->student_number,t->name,t->course,t->usual_score,t->test_score,t->total_score);
                flag = 0;
            }
            else
                break;
            t = t->next;
        }
        if(flag)
            printf("没有学号为%ld学生信息\n",student_number);
    }
    //判断链表中有没有需查询的数据 看有没有输出
    void serch_date(S *head,char date[])// 姓名  查找学生信息
    {
        S *t = head;
        int flag = 1,i = 1;// flag = 1假设不存在需要查找的姓名
        while( t != NULL )
        {
            while( t != NULL && strcmp(t->name,date) != 0  )
                t = t->next;
            if(t != NULL)
            {
                if(i)
                {
                    printf("班级 \t 学号\t 姓名\t         科目         平时成绩      考试成绩    总成绩\n");//有信息输出时 只输出一次
                    i = 0;
                }
                printf("%d\t%ld\t%-10s       %-10s    %.2f         %.2f       %.2f\n",t->grade,t->student_number,t->name,t->course,t->usual_score,t->test_score,t->total_score);
                flag = 0;//存在查询的学生姓名
            }
            else
                break;
            t = t->next;
        }
        if(flag)//不存在查询的学生姓名
            printf("没有%s信息\n",date);
    }
    void serch_grade(S *head,int grade)// 班级  查找学生信息
    {
        S *t = head;
        int  flag = 1,i = 1;
        while(t != NULL)
        {
            while(  t != NULL && t->grade != grade )//顺序很重要
                t = t->next;
            if(t != NULL)
            {
                if(i)
                {
                    printf("班级 \t 学号\t 姓名\t         科目         平时成绩      考试成绩    总成绩\n");//有信息输出时 只输出一次
                    i = 0;
                }
                printf("%d\t%ld\t%-10s       %-10s    %.2f         %.2f       %.2f\n",t->grade,t->student_number,t->name,t->course,t->usual_score,t->test_score,t->total_score);
                flag = 0;
            }
            else
                break;
            t = t->next;
        }
        if(flag)
            printf("没有%d班信息\n",grade);
    }
    void serch_date_course(S *head,char date[])//根据 课程名 查找学生信息
    {
        S *t = head;
        int  flag = 1,i = 1;
        while(t != NULL)
        {
            while( t != NULL && strcmp(t->course,date) != 0  )
                t = t->next;
            if(t != NULL)
            {
                if(i)
                {
                    printf("班级 \t 学号\t 姓名\t         科目         平时成绩      考试成绩    总成绩\n");//有信息输出时 只输出一次
                    i = 0;
                }
                printf("%d\t%ld\t%-10s       %-10s    %.2f         %.2f       %.2f\n",t->grade,t->student_number,t->name,t->course,t->usual_score,t->test_score,t->total_score);
                flag = 0;
            }
            else
                break;
            t = t->next;
        }
        if(flag)
            printf("没有%s信息\n",date);
    }
    S *sort_total_score(S *head)//根据总分排序 冒泡法 交换值 由于后面函数用到此函数 返回头指针
    {
        S *q = head,*p;
        //交换变量
        int temp1;//课程
        long temp2;//学号
        char temp3[20];//姓名
        char temp4[20];//课程名
        float temp5;//平时成绩
        float temp6;//考试成绩
        float temp7;//总评成绩
        for( ; q!=NULL ; q = q->next)
            for(p = q->next; p != NULL; p = p->next )
            {
                if( q->total_score < p->total_score )
                {
                    temp1 = p->grade;
                    temp2 =  p->student_number;
                    strcpy(temp3, p->name ) ;
                    strcpy( temp4, p->course) ;
                    temp5 =   p->usual_score;
                    temp6 =   p->test_score ;
                    temp7 =  p->total_score ;
                    p->grade = q->grade;
                    p->student_number = q->student_number;
                    strcpy( p->name, q->name ) ;
                    strcpy(  p->course,  q->course) ;
                    p->usual_score =  q->usual_score;
                    p->test_score =  q->test_score ;
                    p->total_score =  q->total_score ;
                    q->grade =  temp1;
                    q->student_number = temp2;
                    strcpy(q->name, temp3 ) ;
                    strcpy( q->course,  temp4) ;
                    q->usual_score =  temp5;
                    q->test_score =  temp6 ;
                    q->total_score =   temp7 ;
                }
            }
        //print(head);
        return head;
    }
    void sort_one_course(S *head,char course[])//按单科成绩从大到小排序
    {
        S *t = head;
        int  flag = 1,i = 1;
        sort_total_score(head);//先按总分排序 找出相应的科目输出
        while(t != NULL)
        {
            while( t != NULL  && strcmp(t->course,course) != 0)
                t = t->next;
            if(t != NULL)
            {
                if(i)
                {
                    printf("班级 \t 学号\t 姓名\t         科目         平时成绩      考试成绩    总成绩\n");//有信息输出时 只输出一次
                    i = 0;
                }
                printf("%d\t%ld\t%-10s       %-10s    %.2f         %.2f       %.2f\n",t->grade,t->student_number,t->name,t->course,t->usual_score,t->test_score,t->total_score);
                flag = 0;
            }
            else
                break;
            t = t->next;
        }
        if(flag)
            printf("没有%s信息\n",course);
    }
    void grade_great_number(S *head,int grade)//班级优秀率 不及格率查询
    {
        float num1 = 0,num2 = 0,num3 = 0;
        int flag = 0;
        S *t = head;
        while(t != NULL)
        {
            while( t != NULL && t->grade != grade )
                t = t->next;
            if(t != NULL)
            {
                flag = 1;//说明有查询班级
                num1++;//班级总人数
                if(t->total_score >= 90)
                    num2++;//优秀人数
                else if(t->total_score < 60)
                    num3++;//不及格人数
            }
            else
                break;
            t = t->next;
        }
        if(flag)
            printf("%d班:\n优秀率:%-5.2f%%   不及格率:%-5.2f%%\n",grade,(num2/num1)*100,(num3/num1)*100) ;
        else
            printf("没有%d班信息!\n",grade);
    }
    S *sort_one_course1(S *head,char course[])//按单科成绩从大到小排序 返回最小值的地址
    {
        S *t = head, *min = NULL;
        int flag = -1;
        sort_total_score(head);
        while(t != NULL)
        {
            while(t != NULL && strcmp(t->course,course) != 0  )
                t = t->next;
            if(t != NULL)
            {
                flag ++;//运算几次就有几个数据
            }
            else
                break;
            min = t;
            t = t->next;
        }
        if(flag)
            return min;
        else
            return NULL;
    }
    void sort_m(S *head,char course[] )//按课程查找最值
    {
        S *t = head,*max,*min =sort_one_course1(head,course) ;
        sort_total_score(head);//先按总分从高到低排序 ,课程的第一个就为最大值
        while( t != NULL && strcmp(t->course,course) != 0  )
        {
            t = t->next;
            if(t == NULL)
                break ;
        }
        max = t;
        if(max != NULL)
        {
            printf("%s最大值学生信息:\n",course);
            printf("班级 \t 学号\t 姓名\t         科目         平时成绩      考试成绩    总成绩\n");
            printf("%d\t%ld\t%-10s       %-10s    %.2f         %.2f       %.2f\n",max->grade,max->student_number,max->name,max->course,max->usual_score,max->test_score,max->total_score);
        }
        else
        {
            printf("没有%s课程信息\n",course);
            return;
        }
        if(min != NULL)
        {
            printf("%s最小值学生信息:\n",course);
            printf("%d\t%ld\t%-10s       %-10s    %.2f         %.2f       %.2f\n",min->grade,min->student_number,min->name,min->course,min->usual_score,min->test_score,min->total_score);
        }
        else
            printf("%s只有1个同学信息,不存在最值\n",course);
    }
    void mean_in(int num)//功能选择模块
    {
    //   int n = 0;
        char date[20],course[20];
        int grade;
        switch(num)
        {
        case 1://信息录入
        {
            p = creat();
            print(p);
            //   printf("%d\n",length(p));
        }
        break;
        case 2://修改信息
            print(change(p));
            break;
        case 3://删除信息
        {
            p =delet(p);
            print(p);
        }
        break;
        case 4://按姓名查询
        {
            printf("请输入需要查询的姓名:\n");
            getchar();//清除缓冲区中的回车符
            serch_date(p,  gets(date));
        }
        break;
        case 5://按班级查询
        {
            printf("请输入要查询的班级:\n");
            scanf("%d",&grade);
            serch_grade(p,grade);
        }
        break;
        case 6://按学号查询
            serch_number(p);
            break;
        case 7://按课程名查询
        {
            printf("请输入需要查询的课程名:\n");
            getchar();//清除缓冲区中的回车符
            serch_date_course(p,gets(date));
        }
        break;
        case 8://按总分排序
            print(sort_total_score(p)) ;
            break;
        case 9://单科成绩排名
        {
            printf("请输入需要排序的课程名:\n");
            getchar();//清除缓冲区中的回车符
            sort_one_course(p,gets(course));
        }
        break;
        case 10://班级优秀率
        {
            printf("请输入需要查询的班级:\n");
            scanf("%d",&grade);
            grade_great_number(p,grade);
        }
        break;
        case 11:
        {
            printf("请输入需要查询的课程的最值:\n");
            getchar();//清除缓冲区中的回车符
            sort_m(p, gets(course));
        }
        break;
        case  12:
        {
            p = creat_file();
            print(p);
        }
        break;
        case  13:
            exit(0);//退出系统
            break;
        }
    }
    int main()
    {
        int num = 0;
        print_menu();//打印功能模块
        print_char();
        while(1)//选择功能
        {
            printf("请选择功能序号(1——13)\n");
            scanf("%d",&num);
            if(!(num >= 1 && num <= 13))
            {
                printf("功能选择有误,请重新选择\n");
                scanf("%d",&num);
            }
            mean_in(num);
            print_char();
        }
        return 0;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值