欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C语言学生管理系统

程序员文章站 2022-03-08 22:54:52
...

C语言课程的结课大作业
然后基本功能都实现了
本博主也爆肝两天才完成这个(不过欣慰的是更加了解了C语言中的指针啊 链表啊)
说实话太基础和底层的东西写起来挺累的

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

typedef struct T_student//使用单向链表 

{

	char id[15];

	char name[10];

	char sex[5];

	char address[30];

	int score;

	struct T_student *pnext; 

}STU;

STU	*pHead =NULL; //定义一个T_studentd的结构体指针,链表头结点 

STU *pEnd=NULL;  //链表的尾 



void printStart();//欢迎窗口 

void inputMessage();//用户输入学生的基本参数 

void insertStu(char *id,char *name,char *sex,char *address,int score);//链表尾添加学生 

void insertStuTail(char *id,char *name,char *sex,char *address,int score);//链表头添加学生

void insertStuA(STU* pTemp,char *id,char *name,char *sex,char *address,int score);//指定位置向后插入学生信息 

void selectStu();//查询学生 

void selectStuById(char *id); //根据学号查找学生

void updateStu();//修改学生信息 

void deleteStu();//删除全部学生信息 			--目前还有问题 

void deleteStu(STU *pTemp);//删除指定学生信息   

void freeLinkData();//清空链表 

void freeLinkData2();//清空链表 

void printLinkData();//遍历链表 

STU* findStuById(char *id); //通过学号找到指定的学生 

void save();//格式化保存学生信息进入文件 

void saveByAdd();//向文件中继续添加 

void load();//读取文件中的学生信息

void sortByStuScore();//根据分数排序 

int LinkLength(); //求链表长度 或者学生个数 

void BubbleSort(STU *pTemp);

double avStu();//计算平均分 

int sumStu();////计算总分 

void swap(int *a,int *b);//int 交换 

void swap(char *a,char *b);//char 交换 



 



char id[10]={0};

char name[10]={0};

char sex[5]={0};

char address[30]={0};

int score=0;

int main()

{

	printf("***欢迎进入瑞卿学生管理系统***\n");

	char command[100];

	printStart();

	printf("******************************\n");

	while(1){

		printf("请输入你要执行的操作:\n");

		scanf("%s",command);

	if(strcmp(command,"select") == 0){

		selectStu();

	}else if(strcmp(command,"insert") == 0){

        	inputMessage();

            insertStu(id,name,sex,address,score);           

            

	}else if(strcmp(command,"insertT") == 0){

          	inputMessage();

            insertStuTail(id,name,sex,address,score);           

           

	}else if(strcmp(command,"insertA") == 0){

			printf("输入指定的学号:");

			scanf("%s",id);

			STU* pTemp=(STU*)malloc(sizeof(STU));

			pTemp=findStuById(id);

			if(pTemp!=NULL){

				//说明找到了

				inputMessage();

	           	insertStuA(pTemp,id,name,sex,address,score);

			}          

	}else if(strcmp(command,"update") == 0){

		updateStu();

	}else if(strcmp(command,"delete") == 0){

		

		printf("请输入您要删除学生的学号:");

		scanf("%s",id);

		STU* pTemp=(STU*)malloc(sizeof(STU));

		pTemp=findStuById(id);

		deleteStu(pTemp);

		

	}else if(strcmp(command,"deleteA") == 0){

		freeLinkData();

		printf("\n全部清空成功!\n");

		

	}else if(strcmp(command,"sort") == 0){

		sortByStuScore();

	}else if(strcmp(command,"exit") == 0){

		break;

	}else if(strcmp(command,"cls") == 0){

		system("cls");

	}else if(strcmp(command,"help") == 0){

		printStart();

	}else if(strcmp(command,"save") == 0){

		save();

		printf("\nsave success!\n");

	}else if(strcmp(command,"load") == 0){

		load();

		printf("\n学生信息load success!\n");

	}else if(strcmp(command,"num") == 0){

		

		int n = LinkLength();

		printf("\n班级总人数为%d\n",n);

	}else if(strcmp(command,"sum") == 0){

		int s =sumStu();

		printf("\n班级总分为%d\n",s);

	}else if(strcmp(command,"ave") == 0){

		double a=avStu();

		printf("\n班级平均分为%.2lf\n",a);

	}else {

		printf("error\n");

	}	

	}

	//释放链表 

	freeLinkData2();

	system("pause"); 

	return 0;

}

void printStart(){



	printf(" 输入help命令获得详细操作\n");

	printf(" 输入insert 进行尾添加学生的操作\n");

	printf(" 输入insertT 进行头添加学生的操作\n");

	printf(" 输入insertA 进行在指定位置向后添加学生的操作\n");

	printf(" 输入delete 进行删除学生的操作\n");

	printf(" 输入deleteA 进行删除所有学生的操作\n");

	printf(" 输入update 进行更新学生的操作\n");

	printf(" 输入select 进行查询学生的操作\n");

	printf(" 输入sort 给学生成绩进行排序\n");

	printf(" 输入num 求班级学生总人数\n");

	printf(" 输入sum 求班级学生总分\n");

	printf(" 输入ave 求班级学生平均分\n");

	printf(" 输入cls 清屏操作\n");

	printf(" 输入save 格式化保存文件\n");

	printf(" 输入load 加载文件\n");

	printf(" 输入exit 退出系统\n");		

	

}

void inputMessage()

{

	printf("enter new student number:");

	scanf("%s", id);

	printf("enter new student name:");

	scanf("%s", name);

	printf("enter new student sex:");

	scanf("%s", sex);

	printf("enter new student address:");

	scanf("%s", address);

	printf("enter new student score:");

	scanf("%d", &score);

}

//保存进文件 

void save()

{

	FILE* fp=NULL;

	STU* pTemp = pHead;

	char strBuff[60]={0};

	char strScore[3]={0};

	if(pHead==NULL)//如果链表为空就 

	{

		printf("\n信息为空\n");

		return ;	

	}

	

	//打开文件

	fp=fopen("stuData.txt","wb+");//以读写的形式 

	if(fp==NULL) //打开失败 

	{

		printf("文件打开失败!");

		return;	

	}

	//操作文件指针 

	while(pTemp)

	{

		//学号赋值

		strcpy(strBuff,pTemp->id);

		strcat(strBuff,"|");

		//姓名赋值

		strcat(strBuff,pTemp->name);

		strcat(strBuff,"|");

		//性别赋值

		strcat(strBuff,pTemp->sex);

		strcat(strBuff,"|");

		//地址赋值

		strcat(strBuff,pTemp->address);

		strcat(strBuff,"|");

		//分数赋值

		itoa(pTemp->score,strScore,10);//把int类型转化成字符串类型,以10进制的形式 

		strcat(strBuff,strScore);

		strcat(strBuff,"\r\n"); //文件结尾是\r\n 

		

		//1*strlen(strBuff)  一次写出这么多字节 1个字节 

		fwrite(strBuff,1,strlen(strBuff),fp);



		

		pTemp=pTemp->pnext;

	}

	//关闭文件 

	fclose(fp);

}

//读取文件 

void load()

{

	FILE* fp;

	char strBuff[60]={0};

		

	char strId[10]={0};

	char strName[10]={0};

	char strSex[5]={0};

	char strAddress[30]={0};

	char strScore[5]={0};

	

	int count=0;//计数器 计算'|'的个数 

	

	fp=fopen("stuData.txt","rb+");

	if(fp==NULL) //打开失败 

	{

		printf("文件打开失败!");

		return;	

	}

	

	//操作指针,读取函数	

	while(fgets(strBuff, sizeof(strBuff)-1,fp)!=NULL) //正常读入 

 	{

 		int i=0;

 		count=0; //计数器归0 

	 	int j=0;

	 	

	 	for(i=0;strBuff[i] !='\r';i++)

	 	{

	 		if(count==0) //学号 

	 		{

		 		strId[i]=strBuff[i];

				 if(strBuff[i]=='|')

				 {

				 	strId[i]='\0';

 					count++;

 				} 

		 	}

	 		else if(count==1) //姓名

	 		{

				

		 		strName[j++]=strBuff[i];

 			

				 if(strBuff[i]=='|')

				 {

				 	j--;

				 	strName[j]='\0';

 					count++;

 					j=0;	

 				}  

 					

		 	}

			else if(count==2) //性别

			{

				

				strSex[j++]=strBuff[i];

				

				 if(strBuff[i]=='|')

				 {

				 	j--;

				 	strSex[j]='\0';

 					count++;

 					j=0;

 				} 

 						

			}

			else if(count==3) //住址

			{

				

				strAddress[j++]=strBuff[i];

				 if(strBuff[i]=='|')

				 {

				 	j--;

				 	strAddress[j]='\0';

 					count++;

 					j=0; 

 				} 

 				

			}

			else if(count==4) //分数 

			{

				strScore[j++]=strBuff[i];

				

			}

			

	 	}

	 //atoi将字符串转换成int 

 	//插入到链表

 	insertStu(strId,strName,strSex,strAddress,atoi(strScore));

	 	

 	}

 	

	  

	fclose(fp);

}

void insertStu(char *id,char *name,char *sex,char *address,int score)

{

	//非空查询 

	if(id==NULL||name==NULL||sex==NULL||address==NULL||score<0)

	{

		printf("输入错误!");

		return;

	}

	//创建一个节点

	STU* pTemp=(STU*)malloc(sizeof(STU));

	//节点初始化

	strcpy(pTemp->id,id);

	strcpy(pTemp->name,name);

	strcpy(pTemp->sex,sex);

	strcpy(pTemp->address,address);

	pTemp->score=score;

	pTemp->pnext=NULL;

	

	//将节点和链表连接(这是一个头结点不为空的链表 简称非空头链表)

	 if(pHead==NULL||pEnd==NULL) //如果链表为空 

	 {

 		pHead=pTemp;

 	//	pEnd=pTemp; 

	 }else

	 {

 		pEnd->pnext=pTemp;

	//	pEnd=pTemp; 

 	 } 

 	 pEnd=pTemp;

 	 

	 printf("学生数据添加完成\n\n"); 

 

}

void insertStuTail(char *id,char *name,char *sex,char *address,int score)

{

		//非空查询 

	if(id==NULL||name==NULL||sex==NULL||address==NULL||score<0)

	{

		printf("输入错误!");

		return;

	}

	

	//创建一个节点

	STU* pTemp=(STU*)malloc(sizeof(STU));

	//节点初始化

	strcpy(pTemp->id,id);

	strcpy(pTemp->name,name);

	strcpy(pTemp->sex,sex);

	strcpy(pTemp->address,address);

	pTemp->score=score;

	pTemp->pnext=NULL;

	

	//将节点和链表连接(这是一个头结点不为空的链表 简称非空头链表)

	 if(pHead==NULL||pEnd==NULL) //如果链表为空 

	 {

 		//pHead=pTemp;

 		pEnd=pTemp; 

	 }else

	 {

 		pTemp->pnext=pHead;

 		//pHead=pTemp;

 	 } 

 	 pHead=pTemp;//头向前挪动一个 

 	 

 	  printf("学生数据添加完成\n\n");

}

void selectStu()

{

	int choice;

	printf("输入1为全部查找\n");

	printf("输入2为按照学号查找\n");

	scanf("%d",&choice);

	switch(choice)

	{

		//全部查找

		case 1:printLinkData();

			break;

		//按照学号查找

		case 2:printf("输入需要指定查找的学号:");

			scanf("%s",id);

			selectStuById(id);

			break;

		default:

			break;

	}

	

} 

//清空链表(从头开始清理)   目前还有一点问题 

void freeLinkData()

{

	STU *pTemp = pHead;//记录头结点 

	while(pHead!=pEnd)

	{

		pTemp = pHead;  //记录极点 

		pTemp =NULL;

		pHead=pHead->pnext;//头结点后移 

	} 

	pHead=NULL;

	pEnd=NULL;

	pEnd->pnext=NULL;

	pHead->pnext=NULL;

} 

//清空链表(从头开始清理) 

void freeLinkData2()

{

	STU *pTemp = pHead;//记录头结点 

	while(pTemp!=NULL)

	{

		pTemp = pHead;  //记录极点 

		free(pTemp);//删除节点 

		pTemp=NULL;

		pHead=pHead->pnext;//头结点后移 

	} 

	pHead->pnext=NULL;

} 

//遍历链表 

void printLinkData()

{

	STU *pTemp = pHead;

	while(pTemp!=NULL)

	{

		printf("学号:%s,姓名:%s,性别:%s,住址:%s,分数:%d\n",pTemp->id,pTemp->name,

		pTemp->sex,pTemp->address,pTemp->score); 

		pTemp=pTemp->pnext;

	} 

} 

STU* findStuById(char *id)

{

	

	if(id==NULL)

	{

		printf("学号输入错误!");

		return NULL;

	}

	

	//判断链表是否为空 

	if(pHead==NULL||pEnd==NULL)

	{

		printf("链表为空");

		return NULL;

	} 

	//遍历链表

	STU *pTemp = pHead;

	while(pTemp)

	{

		if(strcmp(pTemp->id,id)==0)//字符串相等的时候 

		{

			return pTemp;	

		}

		pTemp=pTemp->pnext; 

	}

	

	printf("查无此节点\n");

	return NULL;

}

//指定位置插入节点 

void insertStuA(STU* pTemp,char *id,char *name,char *sex,char *address,int score)

{

	//创建节点 

	STU* pInTemp=(STU*)malloc(sizeof(STU));

	//节点初始化

	strcpy(pInTemp->id,id);

	strcpy(pInTemp->name,name);

	strcpy(pInTemp->sex,sex);

	strcpy(pInTemp->address,address);

	pInTemp->score=score;

	pInTemp->pnext=NULL;

	

	if(pTemp==pEnd)//是尾节点的话 

	{

		pEnd->pnext=pInTemp; //		1.先连接 

		pEnd=pInTemp;//			2.pEnd后移 

	}else     //中间节点 

	{

		pInTemp->pnext=pTemp->pnext;

		pTemp->pnext=pInTemp;

		

	}

} 

//根据指定id查找学生信息 

void selectStuById(char *id)

{

	STU* pTemp=(STU*)malloc(sizeof(STU));

	pTemp=findStuById(id);

	if(pTemp!=NULL){

	printf("学号:%s,姓名:%s,性别:%s,住址:%s,分数:%d\n",pTemp->id,pTemp->name,

pTemp->sex,pTemp->address,pTemp->score); 

	}

} 

//修改学生信息 

void updateStu()

{

	printf("请输入您要修改学生的学号:");

	scanf("%s",id);

	STU* pTemp=(STU*)malloc(sizeof(STU));

	pTemp=findStuById(id);

	if(pTemp!=NULL)

	{

		//说明找到了

		printf("\n请输入您要修改的信息\n");

		printf("输入1修改该学生的学号\n"); 

		printf("输入2修改该学生的姓名\n"); 

		printf("输入3修改该学生的性别\n"); 

		printf("输入4修改该学生的住址\n"); 

		printf("输入5修改该学生的分数\n"); 

		printf("输入6完成修改\n\n"); 

		int choice;

		

		while(1)

		{

			printf("请输入你要修改的输入参数如(1~6):"); 

			scanf("%d",&choice); 

			if(choice==6)

			{

				break;

			} 

			switch(choice)

			{

				case 1:

					printf("请输入新的学号:");

					scanf("%s",id);

					strcpy(pTemp->id,id); 

					break;

				case 2:

					printf("请输入新的名字:");

					scanf("%s",name);

					strcpy(pTemp->name,name); 					

					break;

				case 3:

					printf("请输入新的性别:");

					scanf("%s",sex);

					strcpy(pTemp->sex,sex); 					

					break;

				case 4:

					printf("请输入新的地址:");

					scanf("%s",address);

					strcpy(pTemp->address,address); 

					break;

				case 5:

					printf("请输入新的分数:");

					scanf("%d",score);

					pTemp->score=score;

					break;

				default:

					printf("update error\n");

					break;

					

			}

		} 

		printf("update success!!\n\n");

		

	}

}

//全部删除 

void deleteStu()

{

	

}

void deleteStu(STU* pTemp)

{

/*	printf("请输入您要删除学生的学号:");

	scanf("%s",id);

	STU* pTemp=(STU*)malloc(sizeof(STU));

	pTemp=findStuById(id);*/

	if(pTemp!=NULL)

	{

		//说明找到了

		

		if(pHead==pEnd) //1.只有一个节点

		{

			free(pHead);

			pHead=NULL;

			pEnd=NULL;

		}else if(pHead->pnext==pEnd)//2.有两个节点 (头尾节点) 

		{

			if(pTemp==pHead)  //删除的是头结点 

			{

				free(pHead);

				pHead=pEnd;	

			}

			else            //删除的是尾节点 

			{

				free(pEnd);

				pEnd=pHead;

				pHead->pnext=NULL;//一定要把头指针的指针域设为空 

			} 

		}else   //3.有多个节点 

		{

			STU* pNode=pHead;//遍历节点

		 	//删除的是头结点的话 

		 	if(pHead==pTemp)

		 	{

	 			pNode=pHead;

	 			pHead=pHead->pnext;

	 			free(pNode);

	 			pNode=NULL;

	 			printf("delete success!!\n\n");

				return ;

	 		}

			while(pNode!=NULL)

			{

				if(pNode->pnext==pTemp)

				{

					//删除的是尾结点的话

					if(pTemp==pEnd)

					{

						free(pTemp);

						pTemp=NULL;//释放完的指针赋为空 

						pEnd=pNode; 

						pEnd->pnext=NULL;//尾节点的下一个要赋空 

						printf("delete success!!\n\n");

						return ;

					} 

					else//删除的是中间节点 

					{

						STU* pSave=pTemp->pnext;//保存节点  保存指定节点的下一个节点 

						pNode->pnext=pSave;

						free(pTemp);

						pTemp=NULL;//释放完的指针赋为空

						printf("delete success!!\n\n");

						return ;

					} 

					

				}

				pNode=pNode->pnext;

			} 

		}

		

	printf("delete success!!\n\n");

		

	}

}

//分数排序 

void sortByStuScore()

{

	STU* pTemp = pHead;

	

	int len =LinkLength();

	//冒泡排序

	BubbleSort(pTemp);

	//打印链表 

	printLinkData(); 

}

//冒泡排序的主要思想两两相性比较,每比较一次会把一轮最大或最小的数放在最后 

void BubbleSort(STU *pTemp){

	STU *cur,*tail;

	cur=pTemp;

	tail=NULL;

	

	int temp=0;

	char tempId[10]={0};

	char tempName[10]={0};

	char tempSex[5]={0};

	char tempAddress[30]={0};

	

	if(cur==NULL||cur->pnext==NULL){

		return;

	}

	while(cur!=tail){

		while(cur->pnext!=tail){

			if(cur->score < cur->pnext->score){

				

				//交换数据域 

			/*	swap(cur->id,cur->pnext->id);

				swap(cur->name,cur->pnext->name);

				swap(cur->sex,cur->pnext->sex);

				swap(cur->address,cur->pnext->address);

				swap(&(cur->score),&(cur->pnext->score));*/

				

				strcpy(tempId,cur->id);

				strcpy(cur->id,cur->pnext->id);

				strcpy(cur->pnext->id,tempId);

				

				strcpy(tempName,cur->name);

				strcpy(cur->name,cur->pnext->name);

				strcpy(cur->pnext->name,tempName);

				

				strcpy(tempSex,cur->sex);

				strcpy(cur->sex,cur->pnext->sex);

				strcpy(cur->pnext->sex,tempSex);

				

				strcpy(tempAddress,cur->address);

				strcpy(cur->address,cur->pnext->address);

				strcpy(cur->pnext->address,tempAddress);

				

				

				

				temp = cur->score;

				cur->score=cur->pnext->score;

				cur->pnext->score=temp;

				

				

			}

			cur=cur->pnext;

		}

		tail=cur;

		cur=pTemp;

	}

	

}

//字符交换 

void swap(char *a,char *b)

{

	char *temp=NULL;



}

//int数交换 

void swap(int *a,int *b)

{



}



int LinkLength()

{

	STU* pTemp=pHead;

	int len=0;//记录链表的长度 

	//遍历链表

	while(pTemp!=NULL)

	{

		len++;

		pTemp=pTemp->pnext;

	}

	return len;

}

int sumStu()//计算总分 

{

	STU* pTemp = pHead;

	int sum=0;

	while(pTemp!=NULL)

	{

		sum+=pTemp->score;

		pTemp=pTemp->pnext;

	}

	return sum;	

}

double avStu()//计算平均分

{

	return sumStu()/LinkLength();	

}

欢迎界面

C语言学生管理系统

功能1 添加

C语言学生管理系统

功能2 全部查询(遍历链表)

C语言学生管理系统

功能3 指定查询

C语言学生管理系统

功能4 成绩排序

C语言学生管理系统

功能5 更改成员信息

C语言学生管理系统

再次查询

C语言学生管理系统

功能6 求平均分

C语言学生管理系统

功能7 求总人数

C语言学生管理系统

功能8 头添加一个学生信息

C语言学生管理系统

功能9 向指定位置之后添加一个学生

C语言学生管理系统
功能10 删除一个指定学生

C语言学生管理系统

功能11 清屏操作

C语言学生管理系统

C语言学生管理系统

功能12 帮助菜单 help

C语言学生管理系统

功能13 保存文件

C语言学生管理系统

C语言学生管理系统

功能14 关闭程序,重新加载文件

C语言学生管理系统