⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wenjianbaocun.c

📁 自己写的简易学生信息管理系统,有很多不足,希望高手多多指教
💻 C
📖 第 1 页 / 共 3 页
字号:
//=============================头文件=========================
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<conio.h>
#include<stdlib.h>
#include<windows.h>
#include<io.h>
//=========================定义结构体=====================
struct StudentData
{
	char sno[4];
	char name[21];
	int age;
	int score[5];
	int total;
	float avg;
};
struct StudentNode
{
	struct StudentData info;
	struct StudentNode *pre;
	struct StudentNode *next;
}snonode;
struct StudentNode *head=NULL;
struct StudentNode *last=NULL;

//=========================定义全局变量和常量====================
int count=0;
#define SAVED 1
#define NOT_SAVED 0
#define MAX_COUNT 100			// 最大记录数
#define CHPAGE 10				//控制一页显示的记录数
int saved=SAVED;
int USE;//控制学号的状态
//=========================主功能函数=====================
void MainMenu();
void ExitSystem();
void AppendRecord();
void SortData();
void PrintReport();
void SaveData();
void LoadData();
void SearchInfo();
void StatData();

//=====================辅助功能函数==============================
void UpdataTitle(char title[100]);
void ShowMessage(char msg[100]);
int GetString(char buffer[],int Maxlen);
int GetYN(char key);
void Trim(char str[20]);
void LTrim(char str[20]);
void RTrim(char str[20]);
void GoToXY(int x, int y);
void ProductSpace (int len);
void FillSpace (int x,int y,int len,int col);
void ClearMessage();

//====================子功能函数============================

//----------------------录入子功能--------------------------
void AddNewNode(struct StudentData newData);
void InputName(char *name);
void InputAge(char *Age);
int InputScore(int c);
void GetNO(char *sno,int num);
//----------------------打印子功能----------------------------
int AccountTotal(struct StudentNode *);
float AccountAvg(int total);
void PrintLine();
void PrintSortMenu();
//-----------------排序子功能--------------------
void PrintOneStu(struct StudentNode*q);
void SnoAsce();
void SnoDesc();
void TotalScoreAsce();
void TotalScoreDesc();
//-----------------------查找子功能----------------------------
void PrintSearchMenu();
void SearchInfo();
struct StudentNode*SearchByNo();
void DoNO(struct StudentNode *q);
int SearchByName(struct StudentNode *temp[]);
void DoName(struct StudentNode*[],int *);
void DeleteData(struct StudentNode*p);
void SearchOneStudent(struct StudentNode*p);

//--------------------------统计子功能---------------------
void StatTotal(struct StudentNode*pStat);
void StatChinese(struct StudentNode*pStat);
void StatEnglish(struct StudentNode*pStat);
void StatMath(struct StudentNode*pStat);
void StatPhogric(struct StudentNode*pStat);
void StatChemical(struct StudentNode*pStat);
int StatTotalTop3Count();
void SortAvgDesc(int i);
int StatScoreiTop3Count(int k);
//void StatCourseAvg(	float avg[]);
void StatCourseAvg();
//-------------------------保存子功能------------------
int JudgeFilename(char fn[]);
int WriteDataToFile(FILE *fp);


//----------------------------验证合法性---------------------
int JudgeSno(char no[]);
int JuadgeName(char name[]);
int GetYN(char key);

//********************主函数***********************
void main()
{
	do{
		MainMenu();		
		
	}while(1);			
}

//*****************Begin界面菜单输出及调用函数*****************
void MainMenu()
{
	char key;
	int i,width;
	char menulist[9][80]=
	{	
		"1.   Add  student's  info",
			"2.   Sort data",
			"3.   Print  student's  report",
			"4.   Save  data  to  file",
			"5.   Load  data  from  file",
			"6.   Search  students",
			"7.   Stat  Score",
			"0.   Exit",
			"Please Make a choices[0-7]:"
	};
	width=(80-strlen(menulist[2]))/2;
	system("cls");
	UpdataTitle("Main Menu List");
	putchar('\n');
	putchar('\n');
	for(i=0;i<9;i++)
	{
		printf("\n%*s%s",width," ",menulist[i]);
	}
	do{
		
		key=getche();
		if(key>='0'&& key<='7')
		{
			break;
		}
		else
		{
			GoToXY(0,18);
			ShowMessage("Menu item error,allow[0-7]\n");
			ShowMessage("please press any key to continue");
			getch();
			FillSpace(0,18,60,2);
			FillSpace(0,0,60,15);
			GoToXY(0,0);
			UpdataTitle("Main Menu List");
			putchar('\n');
			putchar('\n');
			putchar('\n');
			for(i=0;i<9;i++)
			{
				printf("%*s%s\n",width," ",menulist[i]);
			}
		}
		
	}while(1);
	
	switch(key)
	{
	case '0':ExitSystem();break;
	case '1':AppendRecord();break;
	case '2':SortData();break;
	case '3':PrintReport();break;
	case '4':SaveData();break;
	case '5':LoadData();break;
	case '6':SearchInfo();break;
	case '7':StatData();break;
	}		
}
//*****************End界面菜单输出及调用函数*****************


//****************Begin退出函数********************
void ExitSystem()
{
	char key;
	system("cls");
	UpdataTitle("Exit System");
	putchar('\n');
	if(saved==NOT_SAVED)
	{
		GoToXY(10,10);
		ShowMessage("Are you sure Exit (Y/N):");
		do{
			key=getche();
			if(GetYN(key)==1)
			{
				if(key=='y'||key=='Y')
				{
					exit(0);
				}
				else 
					return;
			}
			
			else 
			{
				GoToXY(0,20);
				ShowMessage("only allow input Y/N(y/n)\n");
				ShowMessage("press any key to continue");
				getch();
				ClearMessage();
				FillSpace(34,10,20,1);
				GoToXY(34,10);	
			}		
		}while(1);
	}
	else
	{
		do{
			GoToXY(0,10);
			ShowMessage("Are you sure Save the Data and Exit (Y/N/C):");
			key=getche();
			if(key=='y'||key=='Y'||key=='N'||key=='n'||key=='c'||key=='C')
			{
				break;
			}
			else
			{
				GoToXY(0,20);
				ShowMessage("only allow input Y/N(y/n/c)\n");
				ShowMessage("press any key to continue");
				getch();
				ClearMessage();
				FillSpace(32,10,20,1);
				GoToXY(32,10);
			}
			
		}while(1);
		
		if(key=='Y'||key=='y')
		{
			SaveData();
			exit(0);
		}
		else if(key=='N'||key=='n')
		{
			exit(0);
		}
		else return;
	}
	
}
//****************End退出函数****************************

//*****************Begin学生信息录入函数****************
/*
	function:学生信息的录入(8项数据)
	param: 
	return: 
*/
void AppendRecord()
{
	struct StudentData newData;
	char no[4],name[21];
	char Age[3];
	int total=0;
	float avg;
	int		i;
	char key;
	int score[5];
	do{
		system("cls");
		UpdataTitle("Append Record");//更新标题头
		if(count>=MAX_COUNT)//记录满,显示提示
		{
			GoToXY(0,20);
			ShowMessage("The record is full:\n");
			ShowMessage("press any key to continue");
			getch();
			ClearMessage();
			break;
		}
		GoToXY(10,7);
		ShowMessage("Sno(*Auto):");
		GetNO(no,count);  //自动获取学号
		printf("%s",no);
		GoToXY(16,9);
		ShowMessage("Name:");
		InputName(name);//输入姓名 
		GoToXY(17,11);
		ShowMessage("Age:");
		InputAge(Age);//输入年龄
		//五门成绩的输入
		GoToXY(46,5);
		ShowMessage("Chinese:");
		score[0]=InputScore(5); //中文的输入
		GoToXY(46,7);
		ShowMessage("English:");
		score[1]=InputScore(7);//英文的输入
		GoToXY(49,9);
		ShowMessage("Math:");	
		score[2]=InputScore(9);//数学的输入
		GoToXY(46,11);
		ShowMessage("Physics:");
		score[3]=InputScore(11);//物理的输入
		GoToXY(45,13);
		ShowMessage("Chemical:");
		score[4]=InputScore(13);//化学的输入
		
		//=================存入结构体中=====================
		strcpy(newData.sno,no);
		strcpy(newData.name,name);
		newData.age=atoi(Age);
		for(i=0;i<5;i++)
		{
			newData.score[i]=score[i];
		}
		//计算总分并存入
		for(i=0;i<5;i++)
		{
			total+=newData.score[i];
		}
		newData.total=total;
		avg=(float)total/5.0f;
		newData.avg=avg;
		
		AddNewNode(newData);  //输入完数据将节点加入到链表
		count++;
		saved=NOT_SAVED;
		do{
			GoToXY(0,16);//提示是否继续输入(Y继续,N返回主菜单)
			ShowMessage("Are you continue to add new student(Y/N):");
			key=getche();
			if(key=='y'||key=='Y'||key=='N'||key=='n')//字符合法
			{
				break;
			}
			else//输入字符不合法
			{	
				GoToXY(0,18);
				ShowMessage("only allow input Y/N(y/n)\n");
				ShowMessage("Press any key to continue");
				getch();
				FillSpace(0,18,50,2);
				GoToXY(41,16);
				ProductSpace(2);
				GoToXY(41,16);
			}
			
		}while(1);
		
		if(key=='y'||key=='Y') //继续录入
			continue;
		else
			return;
		
	}while(1);
	
}

//*****************End学生信息录入函数****************
/*
	function:排序(0返回主菜单,1学号升序,2学号降序,3总分升序,4总分降序)
	param: 
	return: 
*/
void SortData()
{
	char key;
	system("cls");
	UpdataTitle("Sort Data");
	putchar('\n');
	putchar('\n');
	if(count<=0)  //没有记录
	{
		GoToXY(0,20);
		ShowMessage("Have not student record\n");
		ShowMessage("Press any key to continue");
		getch();
	}
	else 
	{
		int menu;
		PrintSortMenu(); //打印排序菜单

//--------------------------验证合法性------------------------------
		do{
			GoToXY(0,15);
			menu=getche();
			if(menu<'0'||menu>'4')
			{
				GoToXY(0,20);
				ShowMessage("SortMenu only allow [0-4]\n");
				ShowMessage("Press any key to continue");
				getch();
				ClearMessage();
				GoToXY(0,15);
				ProductSpace(1);
				GoToXY(0,15);
			}
			else
			{
				break;
			}
		}while(1);
		switch(menu)
		{
		case '1': SnoAsce();break;  //学号升序
		case '2': SnoDesc();break; //学号降序
		case '3': TotalScoreAsce();break;//总分升序
		case '4': TotalScoreDesc();break;//总分降序
		case '0': return;
		}
		GoToXY(0,16);  //排序完是否要打印记录
		ShowMessage("Sort data Success!\n");
		ShowMessage("Do you want to Print?(Y/N):");
		while(1)
		{
			key=getche();
			if(GetYN(key)==1)
			{
				if(key=='Y'||key=='y')
				{
					PrintReport();break;
				}
				else
				{
					return;
				}
			}
			else
			{
				GoToXY(0,20);
				ShowMessage("Error: only allow Y/N/y/n\n");
				ShowMessage("press any key to continue");
				getch();
				ClearMessage();
				GoToXY(strlen("Do you want to Print?(Y/N):"),17);
				ProductSpace(1);
				GoToXY(strlen("Do you want to Print?(Y/N):"),17);
				continue;
			}
		}
	}		
}

/*
	function:打印所有的学生记录
	param: 
	return: 
*/
void PrintReport()
{
	int i=0;
	//float avg[5];
	struct StudentNode *temp;
	temp=head;
	system("cls");
	UpdataTitle("Print Report");
	if(temp==NULL)
	{
		GoToXY(0,20);
		ShowMessage("Have not student record\n");
		ShowMessage("Press any key to continue");
		getch();
	}
	else
	{
		GoToXY(0,4);
		PrintLine();
		while(1)
		{
			if(i<count)
			{
				if(i%CHPAGE==0 && i!=0)
				{
					GoToXY(0,20);
					printf("This page is full %d record\n",CHPAGE);
					ShowMessage("Press any key to next Page");
					getch();
					system("cls");
					UpdataTitle("Print Report");
					GoToXY(0,4);
					PrintLine();
				}
				PrintOneStu(temp);
				i++;
				temp=temp->next;
			}
			else
			{
				GoToXY(0,20);
				ShowMessage("Print Success\n");
				ShowMessage("Press any key to continue");
				getch();
				return;
			}	
		}
	}
}
//====================================================================
/*
	function:数据的保存
	param: 
	return: 
*/
void SaveData()
{
	FILE *fp;
	char key;
	int len;
	char filename[200];
	system("cls");
	UpdataTitle("Save Data To File");
	if(head==NULL)
	{
		GoToXY(0,20);
		ShowMessage("Have not any record\n");
		ShowMessage("press any key to continue");
		getch();
		return;
	}

	GoToXY(10,6);
	ShowMessage("Please input filename not contain < > ? | \\ : \" * ");
	GoToXY(10,8);
	ShowMessage("Filename:");

	do
	{
		do//验证名字的合法性
		{
			len=GetString(filename,30);
			if(JudgeFilename(filename)==1)
			{
				break;
			}
			GoToXY(0,20);
			ShowMessage("Error:filename not contain < > ? | \\ : \" * ");
			ShowMessage("press any key to continu");
			getch();
			ClearMessage();
			GoToXY(19,8);
			ProductSpace(len);
			GoToXY(19,8);
		}while(1);
		
		Trim(filename);
		GoToXY(19,8);
		ProductSpace(len);
		GoToXY(19,8);
		printf("%s",filename);

		if(access(filename,0)==0) //重名,提示是否覆盖
		{
			GoToXY(0,18);
			ShowMessage("Have been existed the filename ,do you want to cover it?(Y/N)");

			do//验证输入字符的合法性
			{
				key=getche();
				if(GetYN(key)==1)
				{
					break;
				}
				GoToXY(0,20);  
				ShowMessage("Error:key only allow (Y/N/y/n)");
				ShowMessage("press any key to continu");
				getch();
				ClearMessage();
				GoToXY(strlen("Have been existed the filename ,do you want to cover it?(Y/N)"),18);
				ProductSpace(2);
				GoToXY(strlen("Have been existed the filename ,do you want to cover it?(Y/N)"),18);
				//FillSpace(0,18,70,1);
				
			}while(1);

			if(key=='Y'||key=='y')  //要覆盖,进行文件创建
			{
				break;
			}
			else continue;	 //不覆盖,重新输入新的文件名
		}

		break;//不重名,进行文件创建
		
	}while(1);

	//-----------文件创建保存---------------
	
	fp=fopen(filename,"w+b");
	if(fp!=NULL)
	{
		if(WriteDataToFile(fp)==1) //写入数据成功
		{
			saved=SAVED;
			GoToXY(0,20);
			ShowMessage("Save the data Success!!!");
			ShowMessage("Press any key to continue");
			getch();
			ClearMessage();
			return;
		}

		GoToXY(0,20);  //数据写入文件不成功
		ShowMessage("Error:Save the data faile\n");
		ShowMessage("Press any key to continue");
		getch();
		ClearMessage();
		return;
	}
	else
	{
		GoToXY(0,20);
		ShowMessage("Error: open the file fail\n");
		ShowMessage("press any key to continue");
		getch();
		ClearMessage();
		return;
	}
}

//====================================================================
int WriteDataToFile(FILE *fp)
{
	struct StudentNode *temp=head;
	while(temp!=NULL)
	{
		fwrite(&(temp->info),sizeof(struct StudentData),1,fp);
		if(ferror(fp))
		{
			ShowMessage("Error:Write the data fail\n");
			return 0;
		}
		temp=temp->next;	
	}
	if(fclose(fp))
	{
		return 0;
	}
	return 1;
}

//==========================================================================
/*
	function:判断文件名是否合法
	param:  filename[] 文件名数组
	return: 1合法,0非法
*/
int JudgeFilename(char fn[])
{
	int i=0;
	int len;
	len=strlen(fn);
	while(1)
	{
		if(fn[i]=='?'||fn[i]=='<'||fn[i]=='>'||fn[i]=='/'||fn[i]==':'||fn[i]=='*'||
				fn[i]=='\\'||fn[i]=='|'||fn[i]=='"')
		{
			return 0;
		}
		i++;
		if(i==len)
		{
			return 1;
		}
	}
}

//===================================================================================
/*
	function:读取文件中的数据
	param: 
	return: 
*/
void LoadData()
{
	
}


/*
	function:查找学生(1学号,2姓名,0返回主菜单)
	param: 
	return: 
*/
void SearchInfo()
{
	struct StudentNode *q;
	struct StudentNode *addr[100];
	int len=0;
	int *plen;
	plen=&len;
	system("cls");
	UpdataTitle("Search Student Info");
	if(count<=0)
	{
		GoToXY(0,20);
		ShowMessage("Have not student record\n");
		ShowMessage("Press any key to continue");
		getch();
		return;
	}
	else
	{
		char menu;
		GoToXY(0,5);
		PrintSearchMenu();
		
		//------------------ 验证menu是否合法----------------------------------
		do{
			GoToXY(53,9);
			menu=getche();
			if(!(menu>='0'&& menu<='2'))
			{
				GoToXY(0,20);
				ShowMessage("Search key allow [0-2]\n");
				ShowMessage("press any key to continue");
				getch();
				ClearMessage();
				GoToXY(0,5);
				ProductSpace(2);
				GoToXY(0,5);
			}
			else 
			{
				break;
			}
			
		}while(1);
		
		switch(menu)
		{
		case '1':q=SearchByNo();DoNO(q);break;
		case '2':len=SearchByName(addr); DoName(addr,plen);break;
		case '0':return;break;
		}
		
	}
	
}

//===========================统计前三甲===========================
/*
	function:统计前三甲的学生(可能多于三个)
	param: 
	return: 
*/
void StatData()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -