C语言之成绩管理系统

基本要求:

1、实现一个简易的成绩系统;

2、每个学生结点包括学号、姓名和3门课程的成绩,要求:

(1)输入若干学生的信息,并存入文件中;

(2)从文件中读取信息构建链表,并显示信息;

(3)根据学号删除指定的学生结点;

(4)插入给定的学生结点;

(5)对学生求平均分;

(6)求课程的最高分和最低分。

3、要求采用模块化设计,独立的功能应在各个自定义函数中实现。数据加载保存可以考虑文件。

一、结构体说明

typedef struct node          //结构体类型 node(链表)
{	
 int id;                     //学生学号
 char name[10];              //学生姓名
 int score[3];               //学生三门课的成绩
 struct node *next;          //下一连接点地址
}STU;                        //取别名STU
typedef struct node SNODE;
STU s[N],st;                 //定义结构体变量数组s[N]与结构体变量st     

二 、函数列表及介绍

SNODE *creat() ;                    //用于创建链表,将文件的数据存入链表中
void print(SNODE *head) ;            //用于输出链表数据
void input();                       //向文件输入信息
SNODE *del(SNODE *head,int id);      //删除函数,删除某指定的学生数据
SNODE *insert(SNODE *head);         //插入函数,在指定学号前插入学生数据
void average(SNODE *head);          //依次求每个人的平均分
void search(SNODE *head);            //求三门成绩各科的最高分和最低分

三 源程序

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 5                     //学生人数为5人,可更新
typedef struct node              //定义结构体类型
{	
 int id;
 char name[10];
 int score[3];
 struct node *next;
}STU;
typedef struct node SNODE;
SNODE s[N],st;                //定义结构体变量


SNODE *creat() ;                 //函数列表,具体功能在“二”中介绍
void print(SNODE *head) ;
void input();
SNODE *del(SNODE *head,int id);
SNODE *insert(SNODE *head);
void average(SNODE *head);
void search(SNODE *head);


int main()
{
	int choice,number;
	SNODE *head;
	printf("----学生成绩系统----\n");
	while(1)                             //在屏幕上输出菜单
	{
printf("\n1.输入信息 \n2.信息存入链表 \n3.读取信息 \n4.删除数据 \n5.插入数据 \n6.计算学生平均分 \n7.求课程最高分和最低分 \n0.退出\n");
printf("please input your choice\n");
scanf("%d",&choice);                      //输入用户选择
switch(choice)                            //八个数字对应不同功能
{
case 1:input();break;                    
case 2:head=creat();break;
case 3: printf("现有信息为:\n");
print(head);                               //输出链表信息
break;
case 4:printf("输入你要删除的学号\n");     
	scanf("%d",&number);
	head=del(head,number);
	printf("现有信息为:\n");
	print(head);break;
case 5:head=insert(head);
	   break;
case 6:	printf("每位同学的平均分为:\n");
	average(head);
	break;
case 7:printf("各科目最高分和最低分为\n");
	search(head);
	break;
case 0:goto end;break;               //用goto语句导至 end。退出循环,结束程序
}
	}
 
end:return 0;
}


SNODE *creat()                            //创建链表的函数,将数据从文件导入链表
{
FILE *fp;
SNODE *h,*s,*r;
h=(SNODE*)malloc(sizeof(SNODE)); 
r=h;
	int i;
	if((fp=fopen("C:\\student.dat","rb"))==NULL)
	{
		printf("cannot open this file!\n");     //打开文件失败的提示
		exit(0);
	}
		for(i=0;i<N;i++)
		{
			fread(&st,sizeof(STU),1,fp);        //读取文件中的信息
            s=(SNODE*)malloc(sizeof(SNODE));   //将结构变量数组中的数据挂上链表
s->id=st.id;  strcpy(s->name,st.name);  s->score[0]=st.score[0];  s->score[1]=st.score[1];  s->score[2]=st.score[2];  
r->next=s;
r=s;
}
r->next='\0';
return h;
}


void print(SNODE *head)  //输出链表的函数
{SNODE *p;
p=head->next;  
if(p==NULL) printf("\nLinkList is NULL!\n");  
else{
	do{	   printf("%-10d%-11s%6d%6d%6d\n",p->id,p->name,p->score[0],p->score[1],p->score[2]);  
	   p=p->next;  
	}while(p!=NULL);
}
}

void input()
{
	FILE *fp;
	int i;
	if((fp=fopen("C:\\student.dat","wb"))==NULL)
	{
		printf("cannot open this file!\n");
		exit(0);
	}
	for(i=0;i<N;i++)
	{
		printf("input \nstudent %d information\n",i+1);
		printf("id:");
		scanf("%d",&s[i].id);
        printf("name:");
		scanf("%s",s[i].name);
        printf("3 score:");
		scanf("%d%d%d",&s[i].score[0],&s[i].score[1],&s[i].score[2]);
	}
	fwrite(s,sizeof(STU),N,fp);
	fclose(fp);
	printf("input voer\n");
}


SNODE *del(SNODE *head,int id)      //以学号为线索删除指定数据
{
	SNODE *p1,*p2;
	p1=head;
	while(id!=p1->id&&p1->next!=NULL)
	{p2=p1; p1=p1->next;}

	if(id==p1->id)                  //找到需删除的学号信息
	{
		if(p1==head) head=p1->next;
		else 
			p2->next=p1->next;
		printf("删除学号:%d 成功!可选择'3'以查看\n",id);
	}
	else printf("找不到学号:%d\n",id);
	return(head);
}


SNODE *insert(SNODE *head)              //插入函数,在指定学好前插入一个学生数据
{
	SNODE *s,*p1,*p2;
	char name[10];
	int x,y,a[3],id;
	s=(SNODE*)malloc(sizeof(SNODE));
	printf("请输入要插入的结点 学号 姓名 三门成绩\n");
	scanf("%d%s%d%d%d",&id,name,&a[0],&a[1],&a[2]);
	s->id=y; strcpy(s->name,name); s->score[0]=a[0]; s->score[1]=a[1]; s->score[2]=a[2];
	printf("要插入在什么学号之前\n");
	scanf("%d",&x);                            //输入插入在某学号之前
	p1=head; p2=head->next;
	while((p2!='\0')&&(p2->id!=x))
	{
		p1=p2;
		p2=p2->next;
	}
	s->next=p2; p1->next=s;
	printf("插入成功!可选择'3'以查看\n");
	return(head);
}

void average(SNODE *head)                     //求取每个学生三门课的平均分数
{SNODE *p;
p=head->next;  
if(p==NULL) printf("\nLinkList is NULL!\n");  
else{

	do{
	   printf("%-10d%-11s%6.2f\n",p->id,p->name,(p->score[0]+p->score[1]+p->score[2])/3.0);  
	   p=p->next;  
	}while(p!=NULL);
}
}


void search(SNODE *head)                  //找出三门课每一门的最高分和最低分
{SNODE *p;
int max[3]={0},min[3]={100,100,100};      //用数组存放三门课的分数并不断更新
int i=0;
p=head->next;  
if(p==NULL) printf("\nLinkList is NULL!\n");  
else{
	do{
		for(i=0;i<3;i++)
		{if(max[i]<p->score[i])
		   max[i]=p->score[i];
		if(min[i]>p->score[i])
		   min[i]=p->score[i];
		}
	   p=p->next;  
	}while(p!=NULL);
}
for(i=0;i<3;i++)
printf("第%d科的最高分和最低分依次为  %d  %d\n",i+1,max[i],min[i]);
}

 四、程序运行结果

 开始菜单界面

读取现有信息

删除某个数据

插入某项数据

求平均分(保留二位小数)

求各科最高分和最低分

、说明

        采用了文件和链表的形式。链表在进行插入,删除等功能时更为便捷,可以通过改变next地址值的办法从而更好地实现功能。而文件可以保存数据,不必每次使用都重新输入,大大提高了该小程序的实用性和功能性。

、总结

      这是我独立完成的一个完整的应用任务,实际代码量大约有110行,包含了6个核心功能,分别是:

         (1)输入若干学生的信息,并存入文件中;

         (2)从文件中读取信息构建链表,并显示信息;

         (3)根据学号删除指定的学生结点;

         (4)插入给定的学生结点;

         (5)对学生求平均分;

         (6)求课程的最高分和最低分,符合课程设计的要求。

         我运用了数组、循环、随机数、判断、指针、链表、文件等多个C语言编程知识,许多无意识的小错漏,很多时候会影响程序的运行。因此,编写代码时的格式应该尤为注意,只有当界面整洁明了,寻找错漏处、修改代码时才会不那么费时费力,也让检查变得更加便捷简单。另外我其实认为本次程序还是有些欠缺。因为编程水平并不高,很多错误可能没有自检发现。如有其他多余错漏之处,望请批评指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值