反面教材:(失败的)学生管理系统

仅供娱乐,请勿参考

说在前面的话

这是我学习程序语言以来的第一个失败的程序……

由于写这一大堆代码的时候才学到数组和字符串而且完全不会用,且除了课设模板完全没有借助任何参考资料,所以相当于写了一大堆乐色orz
要不是有任务在身才不会发出来丢人

不管是下面的话还是测试还是代码都基本没有实际意义
其实发现bug了但没有改

不过好在这并不是正式的课设报告,是自己提前拿来练手的
学校上半学期甚至没开c语言课,如果我课设真这么写怕是得躺着回家

具体的得失在之后会讨论,先看当时一本正经的瞎掰图一乐呵好了。

前言

随着计算机技术和软件技术的飞速发展,计算机及其软件已经成为学校及教师输入,处理,打印学生成绩必不可少的工具。一个合适的学生管理系统能使教师方便快捷的处理学生的成绩,达到事半功倍的效果。
综上所述,由于其实际需要,因此有必要编写一个方便使用的程序管理系统,为学校与教师提供方便快捷处理学生成绩的手段,大力提高学校及教师的工作效率。

1 需求分析

1.1 功能性需求

1.输入学生的学号,姓名,单科成绩,自动计算总分;
2.根据学生学号,姓名,单科成绩和总分,进行从低到高(字典序从上到下)和从高到低(字典序从下到上)两种方式的排序;
3.程序中批量添加学生信息;
4.打印当前程序中存储的学生信息;
5.根据学号或姓名查找并打印某学生的信息;
6.计算并打印各科及总分的平均分(保留两位小数)。

1.2 非功能性需求

1.文字提醒和引导用户输入及处理;
2.对部分错误的输入进行提示和跳出;
3.表格形式打印成绩。

2 概要设计

2.1 系统描述模块图

2.1.1 系统流程描述图

在这里插入图片描述

2.1.2 系统菜单描述图

在这里插入图片描述

3 详细设计

3.1 功能模块描述图

3.1.1 输入模块

在这里插入图片描述

3.1.2 增加模块

在这里插入图片描述

3.1.3 修改模块

在这里插入图片描述

3.1.4 打印模块

在这里插入图片描述

3.1.5 查找模块

在这里插入图片描述

3.1.6 求平均分模块

在这里插入图片描述

4 用户使用说明

按提示操作即可。你要是非得输入些奇怪的东西我也拿你没办法啊.jpg

5 调试与测试

进入系统后,首先提示输入科目数与初始学生数量。格式如下所示:
在这里插入图片描述

输入完毕后,进入菜单:
在这里插入图片描述

打印效果如下:
在这里插入图片描述

进行排序。选择排序功能后进入子菜单:
在这里插入图片描述

以总分从高到低排序为例,操作步骤与效果如图:
在这里插入图片描述

选择批量添加,输入需要添加的学生数量,并分别输入学生信息。步骤及效果如下:
在这里插入图片描述

选择修改功能,输入需要修改的学生学号,然后更改学生的成绩信息,总分会自动重新计算并变化。步骤及效果如下:
在这里插入图片描述
在这里插入图片描述

选择求平均数模块,可选择科目或总分求出平均分。效果如下:
在这里插入图片描述

6 源程序清单

#include<stdio.h>
#include<string.h>

char xm[10000][20];//姓名,以字符串形式存储 
int cj[10000][10]={0};//成绩,第一个下标表示学生编号,第二个下标表示各科成绩 
int zf[10000]={0};//总分 
char kcm[10000][20];//课程名 
char xh[10000][20]={0};//学号 
int pm[10000]={0};//存放排名 
int sr;//判断进行哪种操作 
int ws;//存放位数 
int bh;//编号 

int n;//学生总数(随处理而变化) 
int m;//科目数量 
int i,j,k;//工具人 
int xg;//存放修改需要的数值 

int qws(int a)//求位数函数 
{
	int p;
	if(a==0) return 1;
	for(p=0;a>0;a/=10)
	p++;
	return p;
}

void dyzfc(char a[20],int max)//打印字符串,第一个是要打印的字符串,第二个是单元格长度 
{
	printf("* %s",a);
	for(int i=0;i<=max-2-strlen(a);i++)
	printf(" ");
}

void dysz(int a,int max)//打印数字,第一个变量a是要打印的数字,第二个变量max是当前单元格的长度
{
	printf("* %d",a);
	ws=qws(a);
	for(int k=ws+2;k<=max;k++)
	printf(" ");
	return;
} 

void zfccxddpx(char a[20],char b[20],int pm[10000],int n)//字符串从大到小排序,前两个变量为待排序字符串,第三个为实际排序 ,第四个为学生总数 
{	 
	strlwr(a);
	strlwr(b);
 	for(int j=0;j<strlen(a)||j<strlen(b);j++)
 	{
 		if(a[j]>b[j])
 		{
 			int t=pm[i];
 			pm[i]=pm[i+1];
 			pm[i+1]=t;
 			return;
		}
		else if(a[j]==b[j]) continue;
		else return;
	}
}

void zfccddxpx(char a[20],char b[20],int pm[10000],int n)//字符串从大到小排序,前两个变量为待排序字符串,第三个为实际排序 ,第四个为学生总数 
{	 
	strlwr(a);
	strlwr(b);
 	for(int j=0;j<strlen(a)||j<strlen(b);j++)
 	{
 		if(a[j]<b[j])
 		{
 			int t=pm[i];
 			pm[i]=pm[i+1];
 			pm[i+1]=t;
 			return;
		}
		else if(a[j]==b[j]) continue;
		else return;
	}
}

void szcxddpx(int a,int b,int pm[10000],int n)//数值从小到大排序 
{
	if(a>b)
	{
		int t=pm[i];
		pm[i]=pm[i+1];
		pm[i+1]=t;
	}
}

void szcddxpx(int a,int b,int pm[10000],int n)//数值从大到小排序 
{
	if(a<b)
	{
		int t=pm[i];
		pm[i]=pm[i+1];
		pm[i+1]=t;
	}
}

void wxsz()//输入无效数值时的文字提示 
{
	printf("\n您输入的数值无效!\n\n==========返回菜单==========\n");	
	return;
}

int main()
{
	//输入部分 
	printf("==========欢迎==========\n");
	l1:printf("\n请先输入需要统计的科目数量:");
	scanf("%d",&m);
	if(m==0)//课程输入为0的处理 
	{
		printf("\n**********课程数不得为零!**********\n");
		goto l1;
	}
/*	for(i=1;i<=m;i++)
	{
		printf("\n请输入第%d门课程的名字: ",i);
		scanf("%s",&kcm[i]);
	}*/
	//由于打印课程名到表格里遇到了诸多问题,故去掉了这一步...改用代号描述课程名 
	//这时课程名就没有存在的需要了 我太菜了.jpg 
	printf("\n==========课程设置完成==========\n"); 
	l2:printf("\n==========请输入需要学生的人数==========\n"); 
	printf("\n**********学生总数为10000的整数**********\n");
	printf("\n请输入: ");
	scanf("%d",&n);
	if(n<=0||n>10000)//对输入不在范围内的处理 
	{
		printf("\n**********数据不符合输入范围,请重新输入!**********\n");
		goto l2; 
	}
	printf("\n==========学生人数设置完成==========\n"); 
	printf("\n**********成绩输入范围为0-999的整数**********\n");
	
	for(i=1;i<=n;i++)//输入每个学生的单科成绩 
	{
		pm[i]=i;
		printf("\n请输入第%d名学生的学号: ",i);
		scanf("%s",&xh[i]);
		printf("\n请输入第%d名学生的姓名: ",i);
		scanf("%s",&xm[i]); 
		for(j=1;j<=m;j++)
		{
			printf("\n请输入第%d名学生第%d门课程的成绩: ",i,j);
			scanf("%d",&cj[i][j]);
			zf[i]+=cj[i][j];
		}
		printf("\n==========第%d名学生成绩输入完成==========\n",i);
	}
	
	//处理部分
	
	printf("\n==========学生成绩全部输入完成==========\n");
	
	do
	{	
		printf("\n==========您想进行什么处理?==========\n\n");
		printf("*****1==>进行排序*****\n");
		printf("*****2==>批量添加*****\n");
		printf("*****3==>修改成绩*****\n");
		printf("*****4==>打印名单*****\n");
		printf("*****5==>查找学生*****\n");
		printf("*****6==>求平均分*****\n");
		printf("*****0==>结束程序*****\n");
		printf("\n请选择:");
		scanf("%d",&sr); 
		
		if(sr==1)//排序 
		{
			printf("\n您想依据哪一项进行排序?\n");
			printf("*****1==>学号*****\n");
			printf("*****2==>姓名*****\n");
			printf("*****3==>单科成绩*****\n"); 
			printf("*****4==>总分*****\n"); 
			printf("\n请输入: ");
			scanf("%d",&sr);
			
			if(sr==1)
			{
				printf("\n您想如何排序?\n");
				printf("*****1==>从小到大*****\n");
				printf("*****2==>从大到小*****\n");
				printf("\n请输入: ");
				scanf("%d",&sr);
				
				if(sr==1)
				for(k=0;k<n-1;k++)
				for(i=1;i<n;i++)
				zfccxddpx(xh[pm[i]],xh[pm[i+1]],pm,n);
				
				else if(sr==2)
				for(k=0;k<n-1;k++)
				for(i=1;i<n;i++)
				zfccddxpx(xh[pm[i]],xh[pm[i+1]],pm,n);
				
				else
				wxsz();
			}
			
			else if(sr==2)
			{
				printf("\n您想如何排序?\n");
				printf("*****1==>按字典序从小到大*****\n");
				printf("*****2==>按字典序从大到小*****\n");
				printf("\n请输入: ");
				scanf("%d",&sr);
				
				if(sr==1)
				for(k=0;k<n-1;k++)
				for(i=1;i<n;i++)
				zfccxddpx(xm[pm[i]],xm[pm[i+1]],pm,n);
				
				else if(sr==2)
				for(k=0;k<n-1;k++)
				for(i=1;i<n;i++)
				zfccddxpx(xm[pm[i]],xm[pm[i+1]],pm,n);
				
				else
				wxsz();
			}
			
			
			else if(sr==3)
			{
				do
				{
					printf("\n请输入要排序的科目:");
					scanf("%d",&bh); 
					
					if(bh<=0||bh>m)
					printf("\n请输入有效的数值!\n");
					
				}while(bh<=0||bh>m);
				
				printf("\n您想如何排序?\n");
				printf("*****1==>成绩从低到高*****\n");
				printf("*****2==>成绩从高到低*****\n");
				printf("\n请输入: ");
				scanf("%d",&sr);
				
				if(sr==1)
				{
					for(k=0;k<n-1;k++)
					for(i=1;i<n;i++)
					szcxddpx(cj[pm[i]][bh],cj[pm[i+1]][bh],pm,n);
				}
				
				else if(sr==2)
				{
					for(k=0;k<n-1;k++)
					for(i=1;i<n;i++)
					szcddxpx(cj[pm[i]][bh],cj[pm[i+1]][bh],pm,n);
				}
				
				else
				wxsz();
			}
			
			else if(sr==4)
			{
				printf("\n您想如何排序?\n");
				printf("*****1==>成绩从低到高*****\n");
				printf("*****2==>成绩从高到低*****\n");
				printf("\n请输入: ");
				scanf("%d",&sr);
				
				if(sr==1)
				{
					for(k=0;k<n;k++)
					for(i=1;i<n;i++)
					szcxddpx(zf[pm[i]],zf[pm[i+1]],pm,n);
				}
				
				else if(sr==2)
				{
					for(k=0;k<n;k++)
					for(i=1;i<n;i++)
					szcddxpx(zf[pm[i]],zf[pm[i+1]],pm,n);
				}
				
				else
				wxsz();
			}
			
			else
			wxsz();
			
			printf("\n==========排序完成==========\n");
		}
		
		else if(sr==2)//添加 
		{
			printf("\n*****添加的学生将会依次排列在表格最后*****\n");
			printf("\n请输入要添加的学生个数: ");
			scanf("%d",&sr);
			for(i=n+1;i<=n+sr;i++)
			{
				pm[i]=i;
				printf("\n请输入第%d名学生的学号: ",i);
				scanf("%s",&xh[i]);
				printf("\n请输入第%d名学生的姓名: ",i);
				scanf("%s",&xm[i]); 
				for(j=1;j<=m;j++)
				{
					printf("\n请输入第%d名学生第%d门课程的成绩: ",i,j);
					scanf("%d",&cj[i][j]);
					zf[i]+=cj[i][j];
				}
				printf("\n==========第%d名学生成绩输入完成==========\n",i);
			}
			n+=sr;
			printf("\n==========添加完成==========\n");
		}
		
		else if(sr==3)//修改 
		{
			printf("\n**********注意:修改后请重新排序**********\n");
			do
			{
				int flag=1;
				printf("\n请输入要修改学生的学号: ");
				char xg[20];
				scanf("%s",&xg);
				for(i=1;i<=n;i++)
				{
					if(strcmp(xg,xh[i])==0)
					{
						flag=0;
						for(j=1;j<=m;j++)
						{
							zf[i]-=cj[i][j];
							printf("\n请修改该学生第%d门课程的成绩: ",j);
							scanf("%d",&cj[i][j]);
							zf[i]+=cj[i][j];
						}
						printf("\n==========成绩修改完成==========\n",i);
					}
				}
				
				if(flag==1)
				printf("\n未找到该学生!\n");
				
				printf("\n要继续修改吗?\n");
				printf("\n*****1==>继续*****\n");
				printf("\n*****其余数==>退出*****\n");
				printf("\n请输入: ");
				scanf("%d",&bh);
			}while(bh==1);
		}
		
		else if(sr==4)//打印 
		{
			printf("\n打印格式为:\n学号/姓名");
			for(i=1;i<=m;i++)
			printf("/科目%d",i);
			printf("/总分\n");
			printf("\n***********************");//表格顶部的一行 
			for(i=0;i<m;i++)
			printf("******");
			printf("*******\n");
			printf("***********************");//再来一行 
			for(k=0;k<m;k++)
			printf("******");
			printf("*******\n");
			
			for(i=1;i<=n;i++)
			{
				dyzfc(xh[pm[i]],10);//学号 
				dyzfc(xm[pm[i]],10);//姓名 
				for(j=1;j<=m;j++)//各科分数 
				dysz(cj[pm[i]][j],5);
				dysz(zf[pm[i]],6);//总分
				printf("*");//打印右边界
				printf("\n***********************");//打印分隔线 
				for(k=0;k<m;k++)
				printf("******");
				printf("*******\n");
			}
			printf("***********************");//我觉得最后再来一行更好看(狗头 
			for(k=0;k<m;k++)
			printf("******");
			printf("*******\n");
			
			
			printf("\n==========打印完成==========\n");
		}
		
		else if(sr==5)//查找 
		{
			printf("\n==========您想以哪种形式查找学生?==========\n");
			printf("\n*****1==>姓名查找*****\n");
			printf("\n*****2==>学号查找*****\n");
			printf("\n请输入: ");
			scanf("%d",&bh); 
			if(bh!=1&&bh!=2) wxsz();
			
			char cz[20];
			
			if(bh==1)
			{
				printf("\n请输入待查找的学生姓名: ");
				scanf("%s",&cz);
				for(i=1;i<=n;i++)
				{
					if(strcmp(cz,xm[i])==0)
					{
						printf("\n==========找到学生==========\n"); 
						printf("\n打印格式为:\n学号/姓名");
						for(i=1;i<=m;i++)
						printf("/科目%d",i);
						printf("/总分\n\n");
						dyzfc(xh[pm[i]],10);//学号 
						dyzfc(xm[pm[i]],10);//姓名 
						for(j=1;j<=m;j++)//各科分数 
						dysz(cj[pm[i]][j],5);
						dysz(zf[pm[i]],6);//总分
						printf("*\n");//打印右边界
						break;
					}
				}
				if(i==n+1) printf("\n**********未找到该学生!**********\n");
			}
			
			if(bh==2)
			{
				printf("\n请输入待查找的学生学号: ");
				scanf("%s",&cz);
				for(i=1;i<=n;i++)
				{
					if(strcmp(cz,xh[i])==0)
					{
						printf("\n==========找到学生==========\n"); 
						dyzfc(xh[pm[i]],10);//学号 
						dyzfc(xm[pm[i]],10);//姓名 
						for(j=1;j<=m;j++)//各科分数 
						dysz(cj[pm[i]][j],5);
						dysz(zf[pm[i]],6);//总分
						printf("*");//打印右边界
						break;
					}
				}
				if(i==n+1) printf("\n**********未找到该学生!**********\n");
			}
			
			printf("\n==========查找结束==========\n");
		}
		
		else if(sr==6)//求平均分 
		{
			double pjf=0;
			
			printf("\n==========您想知道哪一部分的平均分?==========\n");
			for(i=1;i<=m;i++)
			printf("\n*****%d==>科目%d*****",i,i);
			printf("\n*****%d==>总分******\n",i);
			printf("\n请输入: ");
			scanf("%d",&bh);
			
			if(bh>m+1||bh<=0) wxsz();
			else
			{
				if(bh!=m+1)
				{
					for(j=1;j<=n;j++)
					pjf+=cj[j][bh];
					pjf/=n;
					printf("\n==========处理完成==========\n");
					printf("\n第%d门课程的平均分是 %.2lf 分!\n",bh,pjf);
				}
				
				else
				{
					for(i=1;i<=n;i++)
					pjf+=zf[i];
					pjf/=n;
					printf("\n==========处理完成==========\n");
					printf("\n总分的平均分是: %.2lf 分!\n",pjf);
				}
			}
		}
		else if(sr==0)
		break;
		
		else
		wxsz();
		
	}while(1);
	
	printf("\n==========感谢您的使用==========\n");
	
	return 0;
}

7 参考文献

2019级《C语言课程设计A》报告模板
学长的课设报告(不含代码

8 体会与感想

这次课设让我感受到以下几点不足:

1.程序结构不好
大部分程序主体都写在main函数里了,main函数外只定义了几个全局变量和常用的操作。显得程序很臃肿,也不好修改。

2.没写删除功能
对于我目前的思路而言删除这个操作实在是有点麻烦。我用了一大堆数组存放学生信息,又用了另一个单独的数组存放学生排名(关系到打印的顺序),如果要进行删除的话需要删掉后所有数组往前挪一个,排名在他后面的也要+1……很麻烦,我懒得写了才不是我不会

3.对错误输入的纠正力度不够
虽然我在几乎所有的输入处都添加了文字提示,但众所周知用户并不会看这些(苦笑)关于菜单,范围等是数字的错误输入大都做了提示和跳出,但如果输入字符……整个程序直接原地爆炸升天.jpg但如果要搞这个我只能想到用字符串形式存储所有输入再转换。但这个步骤实在是太麻烦了我同样懒的搞orz我还是太菜了.jpg

4.没有输入和打印科目名称
刚开始我是准备这么做的,但我在打印这环节遇到了无法修正的bug,一旦科目输入汉字的时候无论如何写循环都没法让所有的表格对齐,打印出来之后就是歪歪扭扭的……觉得输入英文科目很奇怪而且英文名称的长度太长了影响打印出来的效果,所以只能把这项功能砍掉了……以后也许有更合适的解决方案。

//以上是之前写课设报告的时候写的

至于现在,那槽点可就一抓一大把了……多到我自己都看不下去。

因为我当时压根不知道那是什么鬼东西现在也没学,这一大堆玩意并没有涉及到文件的输入输出,换句话说即使不考虑bug,实用性也是无限接近于0的。处理一堆没保存的数据对于用户而言没有任何意义,总不能要用户自己复制粘贴输入在复制输出粘贴出去吧……

其次由于当时没学到结构体,更别提链表这种数据结构的知识,所以用了一大堆数组来存放数据……不仅写起来相当的麻烦,各种操作也相当不方便。不用链表实现删除操作着实有亿点点麻烦,搞的我直接放弃治疗了……

还有一些更让我现在看起来哭笑不得的东西:当时我甚至不知道输出有补齐这回事,居中之类的就更别提了……
自学光学语法不打基础,害人不浅啊

一本正经的写了一大堆循环嵌套来手动创造补齐……以及丑得要死的菜单和表格。不知道肝了多久的循环才肝出来orz这种糟糕的写法还导致学生姓名根本用不了中文,否则bug接踵而至。以及各种拼音缩写命名,写到后面自己都不知道自己在写什么。
才不是英语偏科

关于纠错,直到目前除了判断范围我现在也没什么纠正输入的方法,尤其是关于输入数据的类型和变量类型不匹配的时候。
也不是懒的去百度

唯一的思路就是全用字符数组或者string存然后再转换和判断。也许vector容器能更好用些?总之是还没接触到orz

现在老是抱怨一些同学大多数从知识上已经是学弟了的码风内容繁琐排版杂乱,回看自己当时的码风,无言以对……除了缩进和花括号和我现在敲出来的别无二致,诸如空行,程序结构的安排,变量命名和时间复杂度的优化排序用的甚至还是冒泡,真的是怎么看怎么难受。

尤其是空行,现在看来感觉该空的地方(我习惯在不同功能的代码块之间空行)全连在了一起,不该空的地方在使劲空行,不仅结构看的非常的难受,还活生生把代码量飚到了小五百行……

看看这一堆功能都写到主函数的乐色只想敲死自己

如果不是要求,我只想把这一大堆玩意扔进回收站清空几个来回,谁会发出来丢人啊.jpg

算了算了,权当图一乐呵吧。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值