C语言学生学情管理系统((1)易修改扩展(2)链表(3)模糊检索(4)统计分析)

目录

题目如下:

运行截图:

 主界面

 成绩统计

 模糊检索

 结构体以及链

表操作

代码如下:

end

该代码易于扩展,如果要修改学科数量,直接改开头的宏变量就行。

流程图后补

题目如下:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAVG9fX2V2b2x2ZQ==,size_20,color_FFFFFF,t_70,g_se,x_16

运行截图:

 主界面

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAVG9fX2V2b2x2ZQ==,size_20,color_FFFFFF,t_70,g_se,x_16

 成绩统计

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAVG9fX2V2b2x2ZQ==,size_20,color_FFFFFF,t_70,g_se,x_16

 模糊检索

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAVG9fX2V2b2x2ZQ==,size_20,color_FFFFFF,t_70,g_se,x_16

 结构体以及链

表操作

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAVG9fX2V2b2x2ZQ==,size_20,color_FFFFFF,t_70,g_se,x_16

代码如下:

#include<stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 3
char *disciplines[N]={"高数","英语","量子力学"};
typedef struct
{
    char no[10];
    char name[20];
    int Class;
    int height;
    int weight;
    int grade[N];
    char address[30];
    char telNum[12];
    char QQ[20];
    char speciality[20];
    int rank;
    char teachName[20] ;
    char teachNum[11];
} student;

typedef struct Node  //链表结点
{
    student stu;
    struct Node* next;
} Node,*LinkNode;

/* 可分以下三个模块完成功能的设计
1.链表操作
2.文件操作
3.学生学情信息操作
*/
//-------------链表操作begin-------------
void Initial(LinkNode &L)   //初始化链表头结点
{
    L=new Node;
    L->next=NULL;
}

void Destory(LinkNode &L)  //3.销毁单链表
{
    while(L)
    {  //L-next为空时,当前的L没办法释放,所以是L
        LinkNode p = L;
        L = L->next;
        delete p;
    }
}

void add(LinkNode &L,student s)  //插入到首元素
{
    LinkNode p=new Node;
    p->stu=s;
    p->next=L->next;
    L->next=p; //插入到链表中
}

bool existNumber(char *s)   //检查(名字)字符串中是否含有数字
{
    int len=strlen(s);
    int i;
    for(i=0;i<len;i++)
        if(s[i]>='0' && s[i]<='9')
            return true;
    return false;
}

bool isMatched(char *t,char *key)  //模糊查询算法   查看目标字符串中是否含有关键词key
{  //字符串支持 下标读取 欧耶!!
    //为了简便
    //关键词是连续的字符串子序列,没有分开的情况 比如key中 tech ,目标串中不需要考虑tec#h
    int n=strlen(t);
    int m=strlen(key);
    int i=0,j=0;
    int count=0;
    if(n>=m)   //key串长度大于目标串时 没有比较的需要
    { //模式串匹配 暴力搜索
        while(i<n && j<m)
        {
            count++;
            if(t[i]==key[j])
            {
                j++;
                i++;
            }
            else
            {
                i++;
                j=0;
                if(i > n-m)
                    break;
            }
            if(j==m)
                return true;
        }
    }
    return false;
}

void sort(LinkNode &L)  //按照学号排序   算法:直接选择排序
{
    LinkNode first,min,p;
    for(first=L->next ; first->next ; first=first->next) //first下一结点不为空,说明至少有两个元素,则继续排序
    {
        min=first;
        for(p = first ; p ; p=p->next)
            if( strcmp(min->stu.no,p->stu.no) >0 )
                min=p;
        student temp=min->stu;  //交换数据域
        min->stu = first->stu;
        first->stu = temp;
    }
}

void SortIntel(LinkNode &L)  //按照智育排名排序
{
    LinkNode first,min,p;
    for(first=L->next ; first->next ; first=first->next) //first下一结点不为空,说明至少有两个元素,则继续排序
    {
        min=first;
        for(p = first ; p ; p=p->next)
            if( min->stu.rank > p->stu.rank)
                min=p;
        student temp=min->stu;  //交换数据域
        min->stu = first->stu;
        first->stu = temp;
    }
}

//-------------链表操作end-------------------
//-------------文件操作begin-----------------
void readFrom(char *filename,LinkNode &L) //文件读取到链表上
{
    FILE *fp;
    fp=fopen(filename,"r"); //读文件
    if(fp==0)
    {
        printf("文件打开失败!");
    }
    else
    {
        LinkNode p=L;
        while(!feof(fp)) //指针不到末尾
        {
            p->next=new Node;
            p=p->next;
            fscanf(fp,"%12s %12s %5d %5d %5d",p->stu.no,p->stu.name,&p->stu.Class,&p->stu.height,&p->stu.weight);
            int i;
            for(i=0;i<N;i++)
                fscanf(fp,"%5d",&p->stu.grade[i]);
            fscanf(fp,"%12s %13s %12s %12s",p->stu.address,p->stu.telNum,p->stu.QQ,p->stu.speciality);
            fscanf(fp,"%5d %12s %12s\n",&p->stu.rank,p->stu.teachName,p->stu.teachNum);
        }
        p->next=NULL; //链表的尾结点的next指向NULL
    }
    fclose(fp);
}

void WriteAdd(char *filename,student s) //添加的信息 以添加的方式写入文件
{
    FILE *fp;
    fp=fopen(filename,"a+");
    if(fp==0)
    {
        printf("文件打开失败!");
    }
    else
    {
        fprintf(fp,"%12s %12s %5d %5d %5d",s.no,s.name,s.Class,s.height,s.weight);
        int i;
        for(i=0;i<N;i++)
            fprintf(fp,"%5d",s.grade[i]);//N门课的成绩
        fprintf(fp,"%12s %13s %12s %12s",s.address,s.telNum,s.QQ,s.speciality) ;
        fprintf(fp,"%5d %12s %12s\n",s.rank,s.teachName,s.teachNum);
        printf("存入一条记录到文件");
    }
    fclose(fp);
}

void WriteTo(char *filename,LinkNode &L) //链表元素存放在文件中  修改删除 覆盖式写入
{
    LinkNode p=L->next;
    FILE *fp;
    fp=fopen(filename,"w+");
    if(fp==0)
    {
        printf("文件打开失败!");
    }
    else
    {
        while(p)
        {
            fprintf(fp,"%12s %12s %5d %5d %5d",p->stu.no,p->stu.name,p->stu.Class,p->stu.height,p->stu.weight);
            int i;
            for(i=0;i<N;i++)
                fprintf(fp,"%5d",p->stu.grade[i]);//N门课的成绩
            fprintf(fp,"%12s %12s %12s %12s",p->stu.address,p->stu.telNum,p->stu.QQ,p->stu.speciality) ;
            fprintf(fp,"%5d %12s %12s\n",p->stu.rank,p->stu.teachName,p->stu.teachNum);
            p=p->next;
        }
    }
    fclose(fp);
}

//-------------文件操作end-------------------
//-------------学生信息操作begin-------------
void printRow()
{
    printf("学号\t  姓名	   班级	 身高  体重 ");
    int i;
    for(i=0;i<N;i++)
        printf("%-5s",disciplines[i]);
    printf("\t地址	 电话号码     QQ	   特长    智育排名  教师姓名  教师手机号\n");
}

void addStudent(char *filename)
{
    student s;

    printf("请输入以下信息:\n");			//getchar();
    printf("学号:"); scanf("%s",s.no); 		//getchar();
    printf("姓名:"); scanf("%s",s.name);	//getchar();
    while(true)
    {
        if(existNumber(s.name))
        {
            printf("名字中有数字,请重新输入:");
            scanf("%s",s.name);
        }
        else
            break;
    }

    printf("班级:"); scanf("%d",&s.Class);	//getchar();
    printf("身高:"); scanf("%d",&s.height);	//getchar();
    printf("体重:"); scanf("%d",&s.weight);
    int i;
    for(i=0;i<N;i++)
    {
        while(1)
        {
            printf("%s:",disciplines[i]);
            scanf("%d",&s.grade[i]);
            if( s.grade[i]<0 || s.grade[i]>100)
            {
                printf("成绩输入有误,分数=%d,请重新输入:",s.grade[i]);
                scanf("%d",&s.grade[i]);
            }
            else
                break;
        }
    }
    getchar();
    printf("家庭住址:"); scanf("%s",s.address);	//getchar();
    printf("联系电话:"); scanf("%s",s.telNum);	//getchar();
    printf("QQ:"); 		 scanf("%s",s.QQ);		//getchar();
    printf("特长:"); 	 scanf("%s",s.speciality);//getchar();
    printf("智育排名:"); scanf("%d",&s.rank);	//getchar();
    printf("任课教师姓名:"); scanf("%s",s.teachName);//getchar();
    printf("任课教师手机号:"); scanf("%s",s.teachNum);
    WriteAdd(filename,s);  //将L中的元素添加到文件
}

void updateStudent(student *s)
{
    printf("请输入要修改的内容:\n");
    printf("1、班级\t2、身高\t3、体重\t4、成绩\t5、家庭地址\t6、联系电话\n");
    printf("7、QQ\t8、特长\t9、智育排名\t10、任课教师姓名\t11、任课教师手机号\n");
    printf("请输入序号:");
    int no;
    scanf("%d",&no);
    switch(no)
    {
        case 1:  printf("班级:"); scanf("%d",&s->Class);
            break;
        case 2:  printf("身高:"); scanf("%d",&s->height);
            break;
        case 3:  printf("体重:"); scanf("%d",&s->weight);
            break;
        case 4:  int i;
            for(i=0;i<N;i++)											//修改成绩
                printf("%d %-5s",i+1,disciplines[i]);
            printf("请选择要修改的成绩序号:");
            int choose;
            scanf("%d",&choose);
            while(1)
            {
                if(choose <1 || choose>N)
                {
                    printf("序号输入错误,请重新输入:");
                    scanf("%d",&choose);
                }
                else
                    break;  //没有错误就继续
            }
            printf("原来成绩为:%d ,",s->grade[choose-1]);
            printf("要修改为:"); scanf("%d",&s->grade[choose-1]);
            break;
        case 5:  printf("家庭住址:"); scanf("%s",s->address);
            break;
        case 6:  printf("联系电话:"); scanf("%s",s->telNum);
            break;
        case 7:  printf("QQ:"); 		 scanf("%s",s->QQ);
            break;
        case 8:  printf("特长:"); 	 scanf("%s",s->speciality);
            break;
        case 9:  printf("智育排名:"); scanf("%d",&s->rank);
            break;
        case 10:  printf("任课教师姓名:"); scanf("%s",s->teachName);
            break;
        case 11:  printf("任课教师手机号:"); scanf("%s",s->teachNum);
            break;
    }
}

void addAll(char *filename)
{
    int iskeep=1;
    while(iskeep==1)
    {
        iskeep=0;
        addStudent(filename);
        printf("是否继续录入? \n输入1表示继续 输入0表示退出:");
        scanf("%d",&iskeep);
    }
}

void dispStu(student s)
{
    printf("%-10s %-8s %-5d %-5d %-5d",s.no,s.name,s.Class,s.height,s.weight);
    int i;
    for(i=0;i<N;i++)
        printf("%-5d",s.grade[i]);
    printf("\t%-10s %-12s%-11s %-10s",s.address,s.telNum,s.QQ,s.speciality);
    printf("%-8d %-12s %-10s\n",s.rank,s.teachName,s.teachNum);
}

void dispAll(char *filename)
{
    LinkNode L;
    Initial(L);
    readFrom(filename,L);
    sort(L) ; //先对信息进行按学号排序
    LinkNode p=L->next;
    printRow();
    while(p)   //打印链表中所有的学生信息
    {
        dispStu(p->stu);  //每次迭代显示一条学生信息
        p=p->next;
    }
    Destory(L); //销毁链表,回收内存
}

void update(char *filename)
{		//找到要修改的,修改结点的数据域,然后把链表所有元素 覆盖式地存入文件
    LinkNode L;
    Initial(L);
    readFrom(filename,L);  //读取文件,存到链表

    printf("请在以下2项中选择一项检索\n");
    printf("1 学号 		2 姓名\n");
    printf("请输入序号:");
    int choose;
    scanf("%d",&choose);
    while(true)
    {
        if(choose <1 || choose >3)
        {
            printf("输入有误,请再次输入:");
            scanf("%d",&choose);
        }
        else
            break;
    }
    LinkNode p=L->next ;//指向头结点
    switch(choose) //遍历链表每个结点,
    {
        case 1:    //比较学号
            printf("请输入学号:");
            char no[9];
            getchar();
            gets(no);
            printRow(); //打印 列名
            while(p)
            {
                if(strcmp(p->stu.no,no)==0)
                {
                    dispStu(p->stu);
                    updateStudent(&p->stu);
                    break; //若撤掉break,则可以输出所有匹配的学生信息
                }
                p=p->next;
            }
            break;
        case 2:
            printf("请输入姓名:");
            char name[20];
            getchar();
            gets(name);
            while(p)
            {
                if(strcmp(p->stu.name,name)==0)
                {
                    dispStu(p->stu);
                    updateStudent(&p->stu);
                    break;//若撤掉break,则可以输出所有匹配的学生信息
                }
                p=p->next;
            }
            break;
        default:printf("序号输入错误!\n");
    }
    WriteTo(filename,L);  //覆盖式写入文件 达到修改信息的效果
    Destory(L); //销毁链表,回收内存
}

void delStu(char *filename)  //删除与学号相匹配的
{
    LinkNode L;
    Initial(L);
    readFrom(filename,L);  //读取文件,存到链表
    printf("请在以下2项中选择一项检索\n");
    printf("1 学号 		2 姓名\n");
    printf("请输入序号:");
    int choose;
    scanf("%d",&choose);
    while(true)
    {
        if(choose <1 || choose >2)
        {
            printf("输入有误,请再次输入:");
            scanf("%d",&choose);
        }
        else
            break;
    }
    char no[11],name[12];
    switch(choose)
    {
        case 1:printf("请输入学号:");  scanf("%s",no);break;
        case 2:printf("请输入姓名:");  scanf("%s",name);break;
    }
    while(true)
    {
        readFrom(filename,L);  //读取文件,存到链表
        LinkNode p=L->next,front=L;
        while(p)
        {
            if( choose==1? strcmp(p->stu.no,no)==0 : strcmp(p->stu.name,name)==0  )
            {
                printf("已找到,该学生信息为: \n");
                printRow();
                dispStu(p->stu);
                printf("是否删除该学生信息,若删除,输入1,否则输入0  :");
                int isDel=1;
                scanf("%d",&isDel);
                if(isDel)
                {
                    front->next=p->next;
                    delete p; //删除结点,释放内存
                    p=front->next;
                }
                break;
            }
            else
            {
                front=front->next;
                p=p->next;
            }
        }
        int iskeep;
        printf("是否继续删除?若继续则输入1,否则输入0 :");
        scanf("%d",&iskeep);
        if(iskeep!=1)
            break;
    }
    // 以下覆盖写入文件中,达到删除学生信息的效果
    WriteTo(filename,L);
    Destory(L); //销毁链表,回收内存
}

void search(char *filename)  //返回找到的
{
    LinkNode L;
    Initial(L);
    readFrom(filename,L);

    printf("请在以下三项中选择一项检索\n");
    printf("1 学号 		2 姓名\n3手机号\n");
    printf("请输入序号:");
    int choose;
    scanf("%d",&choose);
    while(true)
    {
        if(choose <1 || choose >3)
        {
            printf("输入有误,请再次输入:");
            scanf("%d",&choose);
        }
        else
            break;
    }
    LinkNode p=L->next ;//指向头结点
    switch(choose) //遍历链表每个结点,
    {
        case 1:    //比较学号
            printf("请输入学号:");
            char no[9];
            getchar();
            gets(no);
            printRow(); //打印 列名
            while(p)
            {
                if(isMatched(p->stu.no,no))
                {
                    dispStu(p->stu);
                    break; //若撤掉break,则可以输出所有匹配的学生信息
                }
                p=p->next;
            }
            break;
        case 2:
            printf("请输入姓名:");
            char name[10];
            getchar();
            gets(name);
            printRow(); //打印 列名
            while(p)
            {
                if(isMatched(p->stu.name,name))
                {
                    dispStu(p->stu);
                    break;//若撤掉break,则可以输出所有匹配的学生信息
                }
                p=p->next;
            }
            break;
        case 3:
            printf("请输入手机号:");
            char num[10];
            getchar();
            scanf("%s",num);
            printRow(); //打印 列名
            while(p)
            {
                if(isMatched(p->stu.telNum,num))
                {
                    dispStu(p->stu);
                    break;//若撤掉break,则可以输出所有匹配的学生信息
                }
                p=p->next;
            }
            break;
        default:printf("序号输入错误!\n");
    }
    Destory(L); //销毁链表,回收内存
}

void scoresSTATIC( char *filename)
{
    LinkNode L;
    Initial(L);
    readFrom(filename,L);  //读取文件,存到链表
    LinkNode p=L->next;
    int maxScore[N];
    int minScore[N];
    float avgScore[N];
    int pass[N];
    int i;
    int num=0;
    if(p)
    {
        for(i=0;i<N;i++)
        {
            minScore[i]=p->stu.grade[i];
            maxScore[i]=p->stu.grade[i];
            avgScore[i]=0;
            pass[i]=0;
        }
    }
    printRow(); //打印 列名
    while(p)   //打印链表中所有的学生信息
    {

        for(i=0;i<N;i++)
        {
            avgScore[i]+=p->stu.grade[i];
            p->stu.grade[i]< minScore[i] ? minScore[i]=p->stu.grade[i] : 1 ;  // 1用来占位
            p->stu.grade[i]> maxScore[i] ? maxScore[i]=p->stu.grade[i] : 1 ;  // 1用来占位
            p->stu.grade[i]> 60 ? pass[i]++ : 1 ;
        }
        dispStu(p->stu);  //每次迭代显示一条学生信息
        p=p->next;
        num++; //学生人数
    }
    if(num>0)    //及格人数+不及格人数=总人数
    {
        for(i=0;i<N;i++)
        {
            avgScore[i]=avgScore[i]/num;
        }
    }
    printf("-------------------------------------------------统计分析--------------------------------------------------");
    printf("\n\t及格人数  不及格人数\t及格率\t平均成绩    最高分\t最低分\n");
    for(i=0;i<N;i++)
    {
        printf("%-8s",disciplines[i]);
        printf("%-12d %-12d %-8.2f %-10.2f %-10d %-10d \n",pass[i],num-pass[i],(pass[i]*1.0)/num ,avgScore[i],maxScore[i],minScore[i]) ;
    }
    Destory(L); //销毁链表,回收内存
}

void intelSort(char *filename)
{
    LinkNode L;
    Initial(L);
    readFrom(filename,L);
    SortIntel(L) ; //先对信息进行按学号排序
    LinkNode p=L->next;
    while(p)   //打印链表中所有的学生信息
    {
        dispStu(p->stu);  //每次迭代显示一条学生信息
        p=p->next;
    }
    Destory(L); //销毁链表,回收内存
}

void menu()
{
    char filename[20]="info.txt";
//	printf("请输入文件名:");
//	scanf("%s",filename);  //
    int n;
    while(1)
    {
        printf("\n-------------------------------------------------------\n");
        printf("-----------------学生学情管理系统设计------------------ \n");
        printf("----------------------菜单----------------------------- \n");
        printf(" 1:信息录入------------| 2:显示------------------------ \n");
        printf(" 3:增加记录------------| 4:修改------------------------  \n");
        printf(" 5:删除----------------| 6:检索------------------------ \n");
        printf(" 7:成绩统计------------| 8:智育排名------------------  \n");
        printf(" 0:退出                |                                \n");
        printf("------------------------------------------------------- \n");
        printf("------------更多功能,请关注公众号:退学通知书---------- \n");
        printf("------------------------------------------------------- \n");
        printf(">>>>>请选择菜单中的一项:");
        scanf("%d",&n);
        if(n==0)
        {
            printf("         see you next time!                 \n");
            printf("               再见!                 		\n");
            break;
        }
        else if(n<0||n>8)
        {
            printf("输入错误!\n");
            system("pause") ;
        }

        switch(n)
        {
            case 1:addAll(filename);				    //信息录入     finished
                break;
            case 2:dispAll(filename);				//显示     	   finished
                break;
            case 3:addStudent(filename);				//增加记录     finished   //错误提示  名字不能有数字 分数0-100
                break;
            case 4:update(filename);					//修改 		   finished   //学号姓名检索
                break;
            case 5:delStu(filename);					//删除 		   finished   //学号姓名检索
                break;
            case 6:search(filename);					//检索 		   finished	  //模糊查询
                break;
            case 7:scoresSTATIC(filename);			//成绩统计     finished
                break;
            case 8:intelSort(filename);		 		//智育排名     finished
                break;
        }
    }
}

//-------------学生信息操作end---------------
int main()
{
    menu();
}

end

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值