课程设计————学生信息管理系统(包含历代思路和代码)

课程设计————学生管理系统(包含历代思路和代码)

一.前言

学生信息管理系统是我第一个独立完成的比较长的代码,也算是花费了一些心血,这个系统是我一点点把它从几百行的代码逐渐优化到上千行,功能从简单到复杂。在这里我把我的思路分享给大家,希望能给大家带来一些帮助。

相比较上一篇博客(学生管理系统)而言,这一篇,主要讲的是我逐步优化的思路和过程。以及在那篇博客后,继续进行的优化。

二.学生管理系统1.0版

1. 实现功能

  • 简单的密码验证
  • 学生信息的录入(链表的创建)
  • 学生信息的增.删.改.查
  • 按照平均分排序输出

2. 函数框架

int main(void)
{
	int a;
	struct student *pHead;
	show1(); 
	while(1)
	{
		system("cls");//清屏
		show2();//界面
		fflush(stdin);
		scanf("%d",&a);
		switch(a)
		{
			case 1:pHead=input();break;//输入 
			case 2:output(pHead);break;//输出 
			case 3:increase(pHead);break;//增加 
			case 4:strike_out(pHead);break;//删除
			case 5:chang(pHead);break;//修改 
			case 6:inquiry(pHead);break;//查询 
			case 7:sore(pHead);break;//排序 
			case 0:exit(0);break;
			default :printf("输入有误请重新输入\n");break; 
		}
		printf("按任意键进行下一步操作\n");
		getch();
	}
}

3. 函数调用关系图

课程设计————学生信息管理系统(包含历代思路和代码)_第1张图片

4. 部分功能函数

  1. 链表的创建输出和增删改查
    这一部分大家可以参考我之前的博客(链表及其简单应用),里面有较详细的说明
  2. 链表的排序
    这一部分在我之前的博客(链表及其简单应用)中也有写到,里面介绍了两种排序,链表的冒泡排序和插入排序。相比较而言,其实插入排序更加简单一点,可能是因为冒泡排序是我接触的第一个排序吧,所以我的代码中几乎都是用冒泡来进行排序的
  3. 密码的输入显示 *
void show1()
{
	char cipher[20]={"123456"},a[20],t;//cioher 表示密码
	int i,j;
	printf("欢迎进入学生信息管理系统\n");
	for(i=0;i<3;i++)
	{
		printf("请输入管理员密码:");	
		for(j=0;a[j-1]!=13;j++)//输入时回车时,停止录入密码
		{
			a[j]=getch();//getch接受键盘输入字符,不显示到屏幕上
			if(a[j]==8&&j>0)//如果输入的是删除键
			{
				printf("\b \b");//用\b和空格覆盖前面的*
				j-=2;//删除数组中的字符
			}		
			else if(j>=0)
				printf("*");
			else //防止删除提示语句
				printf(" ");
		}
		printf("\n");
		a[j-1]='\0';	
		if(strcmp(cipher,a)==0)
	 		return;
	}
	printf("三次输入错误!!!退出系统\n");
	Sleep(150);
	exit(1);
}

5. 源代码

代码地址

学生信息管理2.0版

这个版中,刚刚学习了文件的相关操作,所以将文件的操作加入到其中。

1. 新增功能

  1. 从文件中录入数据
  2. 可以选择多种顺序输出
  3. 将学生信息保存到文件中
  4. 使用多文件保存不同功能的函数

2. 函数框架

int main(void)
{
	struct student *pHead;
	int flag;
	show1();//登录界面 
	pHead=startup();//信息的录入 
	save_3(pHead);//保存到缓存文件中 
	while(1)
	{
		system("cls");
		show3();
		fflush(stdin);
		scanf("%d",&flag);
		switch(flag)
		{
			case 1:increase(pHead);break;//增加  
			case 2:strike_out(pHead);break;//删除 
			case 3:chang(pHead);break;//修改 
			case 4:inquiry(pHead);break;//查询
			case 5:save_3(pHead);
				   output(pHead);
				   pHead=finput(1);break;//输出
			case 6:
			   	   save_3(pHead);
				   save(pHead);
				   pHead=finput(1);break;//保存 
			case 0:exit(0);break;
			default :printf("输入有误请重新输入\n");break; 
		}
		printf("按任意键进行下一步操作\n");
		getch();
	}	
}

3. 函数调用关系图

课程设计————学生信息管理系统(包含历代思路和代码)_第2张图片

4. 部分功能函数

  1. 文件的读
struct student *finput(int a)//文件录入 a控制是否需要输入文件名 
{
	
	FILE *fp;
	struct student *pHead=NULL,*pEnd,*pNew;
	int sum=0,i,j,num;
	char filename[100]=N; 
	if(a==2)
	{
		printf("请输入文件路径及文件名:"); 
		fflush(stdin); 
		gets(filename);
	}
	iCound=0;
	pEnd=pHead=(struct student *)malloc(sizeof(struct student));
	fp=fopen(filename,"rt+");
	if(fp==NULL)
	{
		printf("不能打开文件");
		exit(1); 
	}
	while(1)
	{
		sum=0;
		pNew=(struct student *)malloc(sizeof(struct student));
		fscanf(fp,"%s %s %s",pNew->name,pNew->num,pNew->classes);
		fscanf(fp,"%s %s %s",pNew->score[0],pNew->score[1],pNew->score[2]); 
		for(i=0;i<3;i++)//字符串转换为整数 
		{	
		 	num=0;
			for(j=0;pNew->score[i][j];j++)
				num=num*10+pNew->score[i][j]-'0';	
			sum=sum+num;	
		}	
		pNew->aver=sum*1.0/3;
		if(feof(fp))
			break;
		pEnd->next=pNew;
		pEnd=pNew;
		iCound++;
	}
	pEnd->next=NULL;
	fclose(fp);
	return pHead;
}
  1. 文件的写
void save_3(struct student *pHead)
{
	FILE *fp;
	char filename[100]= N;  
	fp=fopen(filename,"wt");
	if(fp==NULL)
	{
		printf("不能打开文件");
		exit(1); 
	}
	pHead=pHead->next;
	while(pHead)
	{
		fprintf(fp,"%s %s %s ",pHead->name,pHead->num,pHead->classes);
		fprintf(fp,"%s %s %s\n",pHead->score[0],pHead->score[1],pHead->score[2]);
		pHead=pHead->next;
	}
	fclose(fp);
}
  1. 使用参数多次调用排序函数
void output_2(struct student *pHead,int a)//a控制排序依据 //方式2输出 
{
	int i,j,flag;
	struct student *pj_1,*pj,*pj_h;
	for(i=0;i<iCound-1;i++)
		for(j=0,pj=pHead,flag=0;j<iCound-i-1;j++) 
		{
			if(flag==0)
			{
				pj_1=pj;
				pj=pj->next;
				pj_h=pj->next;
			}
			if(flag==1)
			{
				pj_1=pj_1->next;
				pj_h=pj->next;
			}	
			flag=0;
			if(a==2&&(pj->aver)<(pj_h->aver))
			{
				exchange(pj,pj_h,pj_1);
				flag=1;	
			}
			else if(a==3&&strcmp(pj->num,pj_h->num)==1)	
			{
				exchange(pj,pj_h,pj_1);
				flag=1;	
			}
			else if(a==4&&strcmp(pj->classes,pj_h->classes)==1)
			{
				exchange(pj,pj_h,pj_1);
				flag=1;
			}
			else if(a==5&&strcmp(pj->name,pj_h->name)==1)
			{
				exchange(pj,pj_h,pj_1);
				flag=1;
			}
		}
	output_t(pHead);		
} 

5. 源代码

这个代码中我使用的是cfree创建工程文件的方法
其他编译器不知道是否可以正常运行。
如果要运行查看结果,推荐使用c free
代码地址

学生信息管理3.0版

这个版本具体可以看我的上一篇博客。

1. 新增功能

  1. 位运算对密码的加密
  2. 分为三个登录端,学生,教师,管理员

2.源代码

这个代码中我使用的是cfree创建工程文件的方法
其他编译器不知道是否可以正常运行。
如果要运行查看结果,推荐使用c free
代码地址

学生信息管理4.0版

1. 新增功能

  1. 从管理一个班变为管理五个班
  2. 对学生信息的数据结构进行改进,将保存成绩从二维数组改为链表,即十字链表。(老师加的要求)

2. 函数框架

课程设计————学生信息管理系统(包含历代思路和代码)_第3张图片

3. 函数调用关系图

课程设计————学生信息管理系统(包含历代思路和代码)_第4张图片

4. 部分功能函数

  1. 学生信息结构节点的定义
struct score//分数 
{
	char date[20];
	int No;
	struct score *next;
};
struct student
{
	int No; //排名 
	char name[20];//姓名 
	char num[20];//学号 
	char classes[20];//班级 
	struct score *ScorepHead;//分数 
	double aver;//平均分
	struct student *next;//指针域 
}; 
struct student *StupHead[6]; //5个班的头节点 
int iCound[6];//5个班的节点数量
  1. 学生信息链表的创建(文件读入)
struct student *Finput(char filename[]) 
{
	
	FILE *fp;
	struct student *pHead=NULL,*pEnd,*pNew;
	int sum=0,i,j,num;
	iCound[filename[5]-'0'-1]=0;
	pEnd=pHead=(struct student *)malloc(sizeof(struct student));
	fp=fopen(filename,"rt");
	if(fp==NULL)
	{
		printf("不能打开文件");
		exit(1); 
	}
	char a[20];//暂存信息 
	fscanf(fp,"%s",a);
	
	int temp[Classnum]={0};//暂存科目数量 
	while(!feof(fp))
	{
		sum=0;
		pNew=(struct student *)malloc(sizeof(struct student));
		strcpy(pNew->name,a);
		fscanf(fp,"%s %s",pNew->num,pNew->classes);
		
				
		struct score *spEnd,*spNew,*spt; //录入科目成绩 
		pNew->ScorepHead=spEnd=(struct score *)malloc(sizeof(struct score));
		while(1)
		{
			spNew=(struct score *)malloc(sizeof(struct score));
			fscanf(fp,"%s",a);
			if(a[0]<'0'||a[0]>'9'||feof(fp))
				break;
			strcpy(spNew->date,a);
			spEnd->next=spNew;
			spEnd=spNew;	
		}
		spEnd->next=NULL;
		int k;
		for(k=0,spt=pNew->ScorepHead->next;spt!=NULL;spt=spt->next,k++)//字符串转整数 
		{	
			for(j=0,num=0;spt->date[j];j++)
				num=num*10+spt->date[j]-'0';	
			sum=sum+num;
			temp[k]++;	
		} 
		pNew->aver=sum/k;	
			
		iCound[filename[5]-'0'-1]++;
		pEnd->next=pNew;
		pEnd=pNew;
	}
	for(i=0;i<Classnum;i++)
			subject[filename[5]-'0'-1][i]=temp[i]; 
	pEnd->next=NULL;
	fclose(fp);
	return pHead;
}

5. 源代码

这个代码中我使用的是cfree创建工程文件的方法
其他编译器不知道是否可以正常运行。
如果要运行查看结果,推荐使用c free
代码地址

后续可以进行的优化

1.梳理函数调用关系,让代码更加清晰简洁

2.使用MFc或者Esay_x制作图形化界面。

你可能感兴趣的:(c语言)