【ShawnZhang】带你看数据结构——第十三课:学生成绩管理系统

也很久没有更新了,也是因为一直在运用数据结构

分析一个实际问题要从三个方面去考虑,一个是逻辑结构,是线性还是非线性,第二个考虑存储结构是链式还是顺序

在考虑逻辑结构的时候,考虑是一个个顺序排列的话,就用线性表(包括特殊的堆栈和队列),如果是一对多的就选择树或者图

如果是频繁插入就选链式,如果是经常读取就选顺序(数组,结构体数组之类)


在考虑学生成绩管理系统时,学生的成绩肯定选用结构体,因为一个变量有很多的成员变量

由于是一个个的学生,所以我们会选择结构体数组,因为成绩一旦录入,我们很少会去修改,更多的是去查询

当然,你也可以认为频繁插入学生新的成绩选用链式表格,这里,仅提供我写的结构体数组


在数据的保存上,借鉴了CSND网友的部分代码,以获得更好的显示效果

当然我还是在学习,所完成代码的质量可能会有bug,仅供参考:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<conio.h>
int BUBB;int PASS;
#define Esc 27
typedef struct{long number;char name[10];char classname[10];int score[3];int average;int rank;}stu; 
typedef struct{stu date[5];int num;}student;

void Display(student *s);
void Create(student *s);
int check_number(student *s ,long number);
int check_score(int score);
void Delete(student *s);
void Search(student *s);
void bubblesort(student *s);
void fscanfstudent(student *s);
void fprintfstudent(student *s);
void fscanfsettings();

void Display(student *s){
	bubblesort(s);
	puts("____________________________________________________________________ ");
	puts("|                                                                   |");
	puts("|   14  软  本  2  班  学  生  成  绩  管  理  系  统               |");
	puts("|                                                                   |");
	puts("_____________________________________________________________________");
	puts(" ____________________________________________________________________");
	puts("|   学号    | 姓名   |班级    |数学|英语|数据结构|平均分|名次|");
	puts("|-------------------------------------------------------------------|");
	
	for(int i=0;i<s->num;i++)
	printf("|%ld |%s  |%s |%d  |%d  |%d      |%d    |%d  |\n",
		s->date[i].number,s->date[i].name,s->date[i].classname,s->date[i].score[0],s->date[i].score[1],s->date[i].score[2],s->date[i].average,s->date[i].rank);
	puts("|___________________________________________________________________|");
	int j=0;
	printf("请输入对应数字:\n0.退出  1.创建新成绩 2.插入学生成绩 3.查找学生成绩 4.删除学生成绩 5.显示学生成绩\n");
	scanf("%d",&j);
	switch(j){
		case 1:Create(s);break;
		//case 2:Insert(s);break;
		case 3:Search(s);break;
		case 4:Delete(s);break;
		case 5:Display(s);break;
	}
}


void Create(student *s){
	long number;
	char ch,name[10],classname[10];
	int score[3];
	while(1){
		printf("请输入学生学号:");scanf("%ld",&number);if(check_number(s,number)) continue;
		printf("请输入学生姓名:");scanf("%s",name);
		printf("请输入学生班级:");scanf("%s",classname);
		printf("请输入学生《数学》成绩:");scanf("%d",&score[0]);if(check_score(score[0])) continue;
		printf("请输入学生《英语》成绩:");scanf("%d",&score[1]);if(check_score(score[1])) continue;
		printf("请输入学生《数据结构》成绩:");scanf("%d",&score[2]);if(check_score(score[2])) continue;
		break;
	}
	printf("\n\n按Enter键新建学生记录,按Esc键取消新建。\n");
	while(1){
		ch=getch();//确认是否新建记录
		if(ch==Esc) Display(s);
		if(ch=='\r') break;
	}
	s->date[s->num].number=number;
	strcpy(s->date[s->num].name,name);
	strcpy(s->date[s->num].classname,classname);
	s->date[s->num].score[0]=score[0];
	s->date[s->num].score[1]=score[1];
	s->date[s->num].score[2]=score[2];
	s->date[s->num].average=(s->date[s->num].score[0]+s->date[s->num].score[1]+s->date[s->num].score[2])/3;
	(s->num)++;
	Display(s);
}
void Insert(student *s){}



void Delete(student *s){//删除记录
	int A,i;
	char ch;
	printf("请输入需要删除第几个学生的信息:\n");
	scanf("%d",&A);
	printf("\n\n按Enter删除学生记录,按Esc键取消删除。\n");
	while(1){
		ch=getch();
		if(ch==Esc) Display(s);
		if(ch=='\r') break;
	}
	for(i=A;i<s->num-1;i++)
	s->date[i]=s->date[i+1];
	s->num-=1;
	printf("删除成功");
	//fprintfstudent(s);
	Display(s);
}




void Search(student *s){
	int A,i,j=0;
	long number;
	char name[10];
	student r;
	r.num=0;
	printf("请输入:1.按姓名查找   2.按学号查找");
	scanf("%d",&A);
	switch(A){
		case 1:
		printf("请输入查找学生姓名:\n");scanf("%s",name);
		for(i=0;i<s->num;i++){if(!strcmp(s->date[i].name,name))r.date[j++]=s->date[i];}
		r.num=j;
		printf("\n查询名字为“%s”的学生记录结果如下:\n",name);

		break;
		case 2:printf("请输入查找学生学号:");
			scanf("%ld",&number);
			for(i=0;i<s->num;i++){
				if(s->date[i].number==number)
					r.date[j++]=s->date[i];
			}
			r.num=j;
			printf("\n查询学号为%ld的学生记录结果如下:\n",number);break;
	}
	if(r.num==0){
	printf("\n\n\t找不到学生记录!按任意键返回。\n"); 
	getch();
	Display(s);
	}
	puts("\n");
	puts("    ________________________________________________________________________");
	puts("   |   学号    | 姓名 |班级|数学|英语|数据结构|平均分|");
	puts("   |------------------------------------------------------------------------|");
	for(i=0;i<r.num;i++)
		printf("|%ld|%s|%s|%d|%d|%d|%d|\n",
		s->date[i].number,s->date[i].name,s->date[i].classname,s->date[i].score[0],s->date[i].score[1],s->date[i].score[2],s->date[i].average);
	puts("   |________________________________________________________________________|");
	printf("\n\n按任意键返回。");
	getch();
	Display(s);
}




int check_number(student *s ,long number){
	int i,t=0;
	if(number<1000000000||number>2000000000){
		printf("输入有误,学号范围为(1000000000-2000000000),按任意键重新输入!");
		getch();
		return 1;
	}
	for(i=0;i<s->num;i++)
		if(s->date[i].number==number) t++;//如果出现重复学号执行t++
	if(t>0){
		printf("输入有误,输入的学号与已存的学生记录重复,请按任意重新输入!");
		getch();
		return 1;
	}
	else return 0;
}


int check_score(int score){
	if(score<0||score>100){
		printf("输入有误,科目分数范围为(0-100),按任意键重新输入!");
		//fflush(stdin);
		getch();
		return 1;
	}
	else return 0;
}

void bubblesort(student *s){
	int i,j;
	stu temp;
	for(i=0;i<s->num-1;i++)//对学生记录数组进行按分数排序
		for(j=0;j<s->num-i-1;j++)
		if(s->date[j].average<s->date[j+1].average){
			temp=s->date[j];
			s->date[j]=s->date[j+1];
			s->date[j+1]=temp;
		}
		for(i=0;i<s->num;i++)//按下标给学生记录.rank(名次赋值)
			s->date[i].rank=i+1;
		for(i=0;i<s->num;i++)//对平均分相同的学生的名次进行并列
			if(s->date[i].average==s->date[i+1].average)
				s->date[i+1].rank=s->date[i].rank;
			if(BUBB){
				for(i=0;i<s->num-1;i++)//对学生记录数组进行按学号排序
			for(j=0;j<s->num-i-1;j++)
				if(s->date[j].number>s->date[j+1].number){
					temp=s->date[j];
					s->date[j]=s->date[j+1];
					s->date[j+1]=temp;
				}
		}
}
void fscanfstudent(student *s){//把学生记录从硬盘写进内存里
	int i=0;
	FILE *p;
	p=fopen("date.dat","rb");
	if(p==NULL){//检查学生记录是否为空
		p=fopen("date.dat","wt");//学生记录为空,新建一个空白的文本到硬盘里
		s->num=0;
		fclose(p);
		return;
	}
	while(!feof(p)){//从硬盘读取学生记录,直接光标读取到为空,结束循环
	fscanf(p,"%ld%s%s%d%d%d%d\n",
		s->date[i].number,s->date[i].name,s->date[i].classname,s->date[i].score[0],s->date[i].score[1],s->date[i].score[2],s->date[i].average);
		i++;
	}
	bubblesort(s);//写进内存前进行排序
	s->num=i-1;//4.??把学生记录从硬盘写进内存里,读取记录次数比实际多1
	fclose(p);
	}
void fprintfstudent(student *s){//把学生记录从内存写进硬盘
	int i=0;
	FILE *p;
	bubblesort(s);//写进硬盘前进行排序
	p=fopen("date.dat","wt");
	while(i<s->num){
	fprintf(p,"|%ld|%s|%s|%d|%d|%d|%d|\n",
		s->date[i].number,s->date[i].name,s->date[i].classname,s->date[i].score[0],s->date[i].score[1],s->date[i].score[2],s->date[i].average);
	i++;
	}
	fclose(p);
}
void fscanfsettings(){//把设置参数从内存保存到硬盘里
	FILE *p;
	p=fopen("settings.dat","wt");
	fprintf(p,"%d %d",BUBB,PASS);
	fclose(p);
}


void fprintfsettings(){//把设置参数从硬盘写进内存中
	FILE *p;
	p=fopen("settings.dat","rb");
	if(p==NULL){//检查设置参数是否为空
	BUBB=1;//设置默认参数
	PASS=60;//设置默认参数
	p=fopen("settings.dat","wt");//设置参数是否为空,新建一个空白的文本到硬盘里
	fprintf(p,"%d %d",BUBB,PASS);//设置默认参数
	fclose(p);
	return;
	}
	fscanf(p,"%d%d",&BUBB,&PASS);
	fclose(p);
}



int main(){
	student s;
	fprintfsettings();
	fscanfstudent(&s);
	Display(&s);
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值