结构体链表学生信息管理系统

项目需求分析
一、 非功能性需求

  1. 用c语言进行编写
  2. 操作界面和操作方式简单
  3. 故障处理:如果因电脑稳定性和用户操作出现故障,需要进行相关的提示,并且保护数据的完整。
  4. 错误操作提示:出,格式错误,不存在等情况进行相关提示
    二、 功能性需求
  5. 系统启动后,弹出一个用户界面,能实现人机交互的功能。而且只能通过界面菜单命令实现各种功能(包括系统退出功能),可以设计欢迎词。
  6. 录入信息包括班级、姓名、学号、五门课程成绩。
  7. 平均成绩:计算每门课程的平均成绩和学生五门课程的平均成绩并存档计算。

下面的功能性需求需要完成上面三个功能后才能实现

  1. 成绩输出:输出学生的信息和对应的原始成绩以及平均成绩。
  2. 成绩排序(按平均成绩):出排序后的学生信息以及对应的课程成绩和平均成绩
  3. 成绩查找:两种查找方式分别是,按学号查找和按姓名查找
  4. 成绩修改:如果学生的成绩录入错误,可以对学生的成绩进行修改,并且修改之后从新求平均值成绩和重新排序。
  5. 成绩追加:增补遗漏的学生以及对应的信息和对应的课程成绩,并计算出平均成绩,增补以后重新排序,并输出新增学生信息和对应课程成绩和平均成绩。
    附加内容
  6. 成绩删除:如果录入一个不存在学的学生的信息,可以指定学生的信息进行删除。(按学生姓名或者名字删除)
  7. 成绩分段:对学生按不同成次分段
  8. 单科排名:对5门课成绩进行单科排名(并且可以查询某单科成绩的排名,并对单科成绩进行分段)
  9. 文件存储:把学生信息和对应的课程成绩和平均成绩存入到文件中。
  10. 文件输出:输出文件中的内容。
  11. 文件导入:从文件中导入数据到成绩管理系统中,然后进行管理
主文件main.c

#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(stu)

//定义结构体类型
typedef struct Student
{
    char classs[20];//班级
    int num;//学号
    char name[20];//名字
    double score[5];//五科成绩
    double average;//平均成绩
    struct Student *next;//下一个地址
}stu;

//15个选项相关函数
stu *information_entry(stu *head);//信息录入
double *average_score(stu *head);//平均成绩
void score_output(stu *head);//成绩输出
void score_ranking(stu *head);//成绩排名
void single_ranking(stu *head);//单科排名
void score_found(stu *head);//成绩查找
void score_change(stu *head);//成绩修改
void score_add(stu *head);//成绩追加
void score_stage(stu *head);//成绩分段
void single_stage(stu *head);//单科分段
stu *score_delete(stu *head);//成绩删除
void file_conserve(stu *head);//文件存储
void file_input();//文件输入
stu *file_import(stu *head);//文件导入

int fied_judje();//判断函数(用来判断每次选择输入的值与输入是否有误)

int n=0;//全局变量,用来记录录入的加导入的学生数量

int lang_ave;//只要增加数据之后lang_ave==0,
//只有进行第二步求平均值等于1 这样就可以保证
//在求完平均值才能进行其他的

int main()
{
    stu *head=NULL;//链表头地址

    double *ave;//用来接收平均成绩的成绩的返回值

    while(1)
    {
        printf(" *            *\n");
        printf("***    *************                           —————————————————\n");
        printf("  *   *       *     *                           姓名:丁梦迪           \n");
        printf(" *    *       *     *                           班级:1703             \n");
        printf("*     * *************                           学号541713460306       \n");
        printf(" *    *       *     *                          ——————————————————\n");
        printf("  *   *       *     *\n");
        printf(" *     *************\n");
        printf("** *********************  *\n");
        printf("  *                       *\n\n\n");
        printf("*****************************欢迎进入学生信息管理系统*****************************\n");
        printf("**                                                                              **\n");
        printf("** 1. 信息录入     2. 平均成绩     3. 成绩输出     4. 成绩排名     5. 单科排名  **\n");
        printf("**                                                                              **\n");
        printf("** 6. 成绩查找     7. 成绩修改     8. 成绩追加     9. 成绩分段     10.单科分段  **\n");
        printf("**                                                                              **\n");
        printf("** 11.成绩删除     12.文件存储     13.文件输入     14.文件导入     15.我要退出  **\n");
        printf("**                                                                              **\n");
        printf("*****************************输入以上数字执行你的操作*****************************\n");

        int chose_1;
        scanf("%d",&chose_1);//菜单选择
        int lang=0;//用于判断选择是否正确,并且用于选择循环结束的条件
        for(;lang==0;)
        {
            switch(chose_1)
            {
                case 1:
                {head=information_entry(head);//录入信息
                 lang=1;
                 break;
                }

                case 2:
                {
                 if(n==0)
                 {
                     printf("\n<<你还没有录入或者导入成绩~~>>\n");
                 }else
                 {
                     ave=average_score(head);//求平均成绩
                     printf("\n5门课各科平均成绩为:%6.2f %6.2f %6.2f %6.2f %6.2f\n5门课总平均成绩为:%6.2f\n"
                        ,*ave,*(ave+1),*(ave+2),*(ave+3),*(ave+4),*(ave+5));
                 }
                 lang=1;
                 break;
                }
                case 3:
                {if(n==0)
                 {
                     printf("\n<<你还没有录入或者导入成绩~~>>\n");
                 }
                 else
                 {
                     if(lang_ave==0)
                     {
                         printf("\n<<你还没有计算平均成绩>>\n");
                     }else
                     {
                         score_output(head);//成绩输出
                     }
                 }
                 lang=1;
                 break;
                }
                case 4:
                {
                 if(n==0)
                 {
                     printf("\n<<你还没有录入或者导入成绩~~>>\n");
                 }
                 else
                 {
                     if(lang_ave==0)
                     {
                         printf("\n<<你还没有计算平均成绩>>\n");
                     }else
                     {
                         score_ranking(head);//成绩排序
                     }
                 }
                 lang=1;
                 break;
                }
                case 5:
                {
                 if(n==0)
                 {
                     printf("\n<<你还没有录入或者导入成绩~~>>\n");
                 }
                 else
                 {
                     if(lang_ave==0)
                     {
                         printf("\n<<你还没有计算平均成绩>>\n");
                     }else
                     {

                        single_ranking(head);//单科排序
                     }
                 }
                 lang=1;
                 break;
                }
                case 6:
                {
                 if(n==0)
                 {
                     printf("\n<<你还没有录入或者导入成绩~~>>\n");
                 }
                 else
                 {
                     if(lang_ave==0)
                     {
                         printf("\n<<你还没有计算平均成绩>>\n");
                     }else
                     {

                        score_found(head);
                     }
                 }
                 lang=1;
                 break;
                }
                case 7:
                {
                 if(n==0)
                 {
                     printf("\n<<你还没有录入或者导入成绩~~>>\n");
                 }
                 else
                 {
                     if(lang_ave==0)
                     {
                         printf("\n<<你还没有计算平均成绩>>\n");
                     }else
                     {

                        score_change(head);
                     }
                 }
                 lang=1;
                 break;
                }
                case 8:
                {if(n==0)
                 {
                     printf("\n<<你还没有录入或者导入成绩~~>>\n");
                 }
                 else
                 {
                     if(lang_ave==0)
                     {
                         printf("\n<<你还没有计算平均成绩>>\n");
                     }else
                     {

                        score_add(head);//成绩追加
                     }
                 }
                 lang=1;
                 break;
                }
                case 9:
                {
                 if(n==0)
                 {
                     printf("\n<<你还没有录入或者导入成绩~~>>\n");
                 }
                 else
                 {
                     if(lang_ave==0)
                     {
                         printf("\n<<你还没有计算平均成绩>>\n");
                     }else
                     {

                        score_stage(head);//成绩分段
                     }
                 }
                 lang=1;
                 break;
                }
                case 10:
                {if(n==0)
                 {
                     printf("\n<<你还没有录入或者导入成绩~~>>\n");
                 }
                 else
                 {
                     if(lang_ave==0)
                     {
                         printf("\n<<你还没有计算平均成绩>>\n");
                     }else
                     {

                        single_stage(head);;//单科分段
                     }
                 }
                 lang=1;
                 break;
                }
                case 11:
                {if(n==0)
                 {
                     printf("\n<<你还没有录入或者导入成绩~~>>\n");
                 }
                 else
                 {
                     if(lang_ave==0)
                     {
                         printf("\n<<你还没有计算平均成绩>>\n");
                     }else
                     {

                        head=score_delete(head);//成绩删除
                     }
                 }
                 lang=1;
                 break;
                 }
                case 12:
                {if(n==0)
                 {
                     printf("\n<<你还没有录入或者导入成绩~~>>\n");
                 }
                 else
                 {
                     if(lang_ave==0)
                     {
                         printf("\n<<你还没有计算平均成绩>>\n");
                     }else
                     {

                        file_conserve(head);//文件存储
                     }
                 }
                 lang=1;
                 break;
                }
                case 13:file_input();lang=1;break;//文件输入
                case 14:
                {head=file_import(head);//文件导入
                 lang=1;
                 break;
                }
                case 15:printf("\n你已正常学生管理退出系统!\n");exit(1);
                default:printf("\n你的输入有错误请重新输入!\n");scanf("%d",&chose_1);
            }
        }
        printf("\n————————————————————\n返回菜单请输入:1         退出请输入:2\n————————————————————\n");
        int chose_2=fied_judje();//调用判断函数
        if(chose_2==1)
        {
            system("CLS");
            continue;
        }
        else
        {
            printf("\n<<你已正常学生管理退出系统!>>\n");
            exit(1);
        }
    }
    return 0;
}

}
数据录入 information_entry.c

typedef struct Student
{
    char classs[20];//班级
    int num;//学号
    char name[20];//名字
    double score[5];//五科成绩
    double average;//平均成绩
    struct Student *next;//下一个地址
}stu;

stu *information_entry(stu *head)//成绩录入
{
    printf("\n请输入学生的班级、学号、姓名、五门课成绩(数据之间一个空格,请把所有数据输入0结束)~~:\n");
    stu *head1=creatlist(head);
    printf("\n<<学生信息录入成功~~!>>\n");
    return head1;
}
数据录入调用链表creatlist.c

#include <stdlib.h>
#define LEN sizeof(stu)

typedef struct Student
{
    char classs[20];//班级
    int num;//学号
    char name[20];//名字
    double score[5];//五科成绩
    double average;//平均成绩
    struct Student *next;//下一个地址
}stu;
extern n;
stu *creatlist(stu *head)
{

    stu *p1,*p2;
    stu *head1;//如果有数据,把新数据添加到上一次链表的末尾

    p1=p2=( stu *) malloc(LEN);
    scanf("%s %d %s %lf %lf %lf %lf %lf",p1->classs,&p1->num,p1->name,&p1->score[0],
          &p1->score[1],&p1->score[2],&p1->score[3],&p1->score[4]);
    if(n==0)
    {
        head=NULL;
        while(p1->num!=0)
        {
            n=n+1;
            if(n==1)head=p1;
            else p2->next=p1;
            p2=p1;
            p1=(stu *)malloc(LEN);
            scanf("%s %d %s %lf %lf %lf %lf %lf",&p1->classs,&p1->num,&p1->name,&p1->score[0],
                &p1->score[1],&p1->score[2],&p1->score[3],&p1->score[4]);
        }
        p2->next=NULL;
        return head;
    }else//已经存在导入的情况下可以继续连接在在导入链表的末端录入
    {
        stu *p=head;
        int i;
        for(i=1;i<n-1;i++)
        {
            p=p->next;
        }
        p->next=head1;
        int n1=0;
        while(p1->num!=0)
        {
            n=n+1;
            n1++;
            if(n1==1)p->next=p1;
            else p2->next=p1;
            p2=p1;
            p1=(stu *)malloc(LEN);
            scanf("%s %d %s %lf %lf %lf %lf %lf",&p1->classs,&p1->num,&p1->name,&p1->score[0],
                &p1->score[1],&p1->score[2],&p1->score[3],&p1->score[4]);
        }
        p2->next=NULL;
        head->average=0;
        return head;

    }
}
求平均值 average_score.c

#include <stdlib.h>
typedef struct Student
{
    char classs[20];//班级
    int num;//学号
    char name[20];//名字
    double score[5];//五科成绩
    double average;//平均成绩
    struct Student *next;//下一个地址
}stu;
extern lang_ave;

double *average_score(stu *head)//平均成绩
{
    stu *p=head;
    double ave[6];
    int i;
    for(i=0;i<6;i++)
    {
        ave[i]=0;
    }
    int count=0;
    for(;p!=NULL;)
    {
        count++;
        ave[0]=p->score[0]+ave[0];
        ave[1]=p->score[1]+ave[1];
        ave[2]=p->score[2]+ave[2];
        ave[3]=p->score[3]+ave[3];
        ave[4]=p->score[4]+ave[4];
        p=p->next;
    }
    ave[0]=ave[0]/count;
    ave[1]=ave[1]/count;
    ave[2]=ave[2]/count;
    ave[3]=ave[3]/count;
    ave[4]=ave[4]/count;
    ave[5]=(ave[1]+ave[2]+ave[3]+ave[4]+ave[0])/5;
    lang_ave=1;
    return ave;
}
成绩输出 score_output.c

#include <stdlib.h>
typedef struct Student
{
    char classs[20];//班级
    int num;//学号
    char name[20];//名字
    double score[5];//五科成绩
    double average;//平均成绩
    struct Student *next;//下一个地址
}stu;

extern n;

void score_output(stu *head)//成绩输出
{
    stu *p=head;
    int i;
    for(i=0;i<n;i++)
    {
        p->average=(p->score[0]+p->score[1]+p->score[2]+p->score[3]+p->score[4])/5;
        p=p->next;
    }
    printf("\n下面是学生的信息:\n");
    printf("\n班级:          学号:          姓名:          五门成绩:                          平均成绩:\n");
    p=head;
    for(;p!=NULL;)
    {
        printf("%s          %d          %s          %6.2f %6.2f %6.2f %6.2f %6.2f\n",
        p->classs,p->num,p->name,p->score[0],p->score[1],p->score[2],p->score[3],p->score[4],p->average);
        p=p->next;
    }
}
成绩排名 score_ranking.c

typedef struct Student
{
    char classs[20];//班级
    int num;//学号
    char name[20];//名字
    double score[5];//五科成绩
    double average;//平均成绩
    struct Student *next;//下一个地址
}stu;

extern n;

void score_ranking(stu *head)//成绩排名(按平均成绩)
{
    stu *p=head;
    stu sort[n];//排序临时数组
    stu temp;//排序交换
    int i,j,m;

    //求平均值并且把所有学生数据复制到数组
    for(i=0;i<n;i++)
    {
        p->average=(p->score[0]+p->score[1]+p->score[2]+p->score[3]+p->score[4])/5;
        sort[i]=*p;
        p=p->next;
    }
    //按从小到大
    for(i=0;i<n-1;i++)
    {
        m=i;
        for(j=i+1;j<n;j++)
        {
            if(sort[m].average>sort[j].average)
            {
                m=j;
            }
        }
        temp=sort[i];
        sort[i]=sort[m];
        sort[m]=temp;
    }

    //选择输出方式
    int chose1;
    printf("\n———————————————————————————————————");
    printf("\n选择按平均值从大到小输出请输入:1         选择从小到大输出请输入:2\n");
    printf("———————————————————————————————————\n");
    chose1=fied_judje();
    printf("\n下面是学生的信息:\n");
    printf("\n班级:          学号:          姓名:          五门成绩:                          平均成绩:\n");
    if(chose1==1)
    {

        for(i=n-1;i>=0;i--)
        {
            printf("%s          %d          %s          %6.2f %6.2f %6.2f %6.2f %6.2f           %6.2f\n",
            sort[i].classs,sort[i].num,sort[i].name,sort[i].score[0],sort[i].score[1],sort[i].score[2],
            sort[i].score[3],sort[i].score[4],sort[i].average);
        }
    }else
    {
        for(i=0;i<n;i++)
        {
            printf("%s          %d          %s          %6.2f %6.2f %6.2f %6.2f %6.2f           %6.2f\n",
            sort[i].classs,sort[i].num,sort[i].name,sort[i].score[0],sort[i].score[1],sort[i].score[2],
            sort[i].score[3],sort[i].score[4],sort[i].average);
        }
    }
}
单科排名 single_ranking.c

typedef struct Student
{
    char classs[20];//班级
    int num;//学号
    char name[20];//名字
    double score[5];//五科成绩
    double average;//平均成绩
    struct Student *next;//下一个地址
}stu;

extern n;

void single_ranking(stu *head)//单科排名
{

    stu *p;
    stu sort_single[5][n];//排序临时数组
    stu temp;//排序交换

    //把链表复制到5个数组
    int i,j,k,m;
    for(i=0;i<5;i++)
    {
        p=head;
        for(j=0;j<n;j++)
        {
            sort_single[i][j]=*p;
            p=p->next;
        }
    }

    ////按从小到大排序
    for(i=0;i<5;i++)
    {
        for(j=0;j<n-1;j++)
        {
            m=j;
            for(k=j+1;k<n;k++)
            {
                if(sort_single[i][m].score[i]>sort_single[i][k].score[i])
                    m=k;
            }
            temp=sort_single[i][m];
            sort_single[i][m]=sort_single[i][j];
            sort_single[i][j]=temp;
        }
    }
    for(;;)
    {
        int chose_1,chose_2;
        printf("\n请输入按第几科排名:");
        for(;;)
        {
            scanf("%d",&chose_1);
            if(chose_1<=5&&chose_1>=1)
            {
                break;
            }
            else
            {
                printf("\n<<你的输入有错误请重新输入!>>\n");
            }
        }
        printf("\n————————————————————————————————————");
        printf("\n选择按单科从大到小输出请输入:1          选择从小到大输出请输入:2\n");
        printf("—————————————————————————————————————\n");
        chose_2=fied_judje();

        printf("\n下面是学生的信息:\n");
        printf("班级:          学号:          姓名:         第%d科成绩: \n",chose_1);
        //排序输出
        if(chose_2==1)//从大到小
        {
            for(i=n-1;i>=0;i--)
            {
                printf("%s          %d          %s          %6.2f\n",
                        sort_single[chose_1][i].classs,
                        sort_single[chose_1][i].num,
                        sort_single[chose_1][i].name,
                        sort_single[chose_1][i].score[chose_1]);
                     }
        }else//从小到大
        {
            for(i=0;i<n;i++)
            {
                printf("%s          %d          %s          %6.2f\n",
                        sort_single[chose_1][i].classs,
                        sort_single[chose_1][i].num,
                        sort_single[chose_1][i].name,
                        sort_single[chose_1][i].score[chose_1]);
            }
        }
        int chose_3;
        printf("\n——————————————————————————");
        printf("\n继续选择请输入1:           退出单科排序请输入:2\n");
        printf("——————————————————————————\n");
        chose_3=fied_judje();
        if(chose_3==1) continue;
        else break;
    }
}

未完待续请参见结构体链表学生管理系统_2
https://www.imooc.com/article/22418

仅供参考,不足的地方还望原谅!!!
                                        **by:郑轻大学生**
点赞