C语言大作业---学生信息管理系统

xxxx信息管理系统

简介

因为大作业规定的踩分项就那么多,为了不浪费时间 + 得分,就写成这样。现在看看,命名不规范,书写风格糟糕,全塞在一个源代码中······


不过,应付大作业是没问题的
image

实验报告

设计一个成绩管理系统,包括考生成绩数据的增删改查等基本操作,要求编程实现如下菜单驱动的校招成绩管理系统:
  • 使用链表录入每个考生的考号、姓名和笔试面试综测的成绩;
  • 计算每个考生的总分;
  • 按总成绩升序或降序排名;
  • 按考号查询考生排名及其考试成绩;
  • 按姓名修改考试成绩;
  • 输出每个考生的考号、姓名、成绩,以及总分;
  • 将每个考生的记录信息写入文件;
  • 从文件读入每个考生的信息;
要求程序运行后先显示如下菜单,并提示用户输入选项:
* 1.成绩录入
* 2.数据修改
* 3.数据查询
* 4.数据删除
* 5.排名
* 6.打印
* 7.保存
* 8.读入
* 0.退出
* 请选择:
然后,根据用户输入的选项执行相应的操作。
输入输出设计
  • 程序输入数据包括选择值,考生信息。选择值为整型变量,为了方便搭配switch语句.考生信息中,姓名,性别,考号为字符串类型,成绩则为数组,方便访问.对考号的输入格式有检查函数,对非法数据输入有检测.

  • 在保存读入的函数中,对文件指针fp有打开失败的检查及提示.使用的数据类型----链表,也有对动态内存申请不成功的检查及提示.搜索函数,修改函数和排序函数的参数为链表的头节点,函数都会对链表进行检查,特判无元素和只有一个元素.

  • 输出格式与提示格式相同,为了一个大型表格,方便阅读,模拟了一个系统界面,提示用户的体验.函数封装有开始提示及结束提示,可以方便用户使用.另外,增加了一个模拟“初始化”的功能,增加趣味性,让系统界面更加仿真.为了防止出现错误,链表在最后会进行释放,文件在打开后会关闭,提升了程序的稳定性.防御性的代码较多.

代码

点击查看代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
#define maxchar 10
#define maxid 20 

typedef struct student
{
	char name[maxchar];
	char id[maxid];
	char sex[3];
	int score[5];
	struct student* next;
}STU;//定义一个可以存放考生信息的  ****链表
 
void Stu_Input(STU* head);//输入信息
void Stu_Output(STU* head);//打印成绩单
void Stu_Search(STU* head);//根据考号查询****查找算法 ****枚举算法 
void change(STU* head);//根据姓名查找到人以后修改
void Stu_delete(STU* head);//根据姓名删除考生
int JudgeID(char mid[]);//判断考号是否输入正确
void save_file(STU* head);//保存链表内容到文件****文件操作 
STU* free_head(STU* head);//释放链表
void sort(STU *head,int (*cmp)(int,int));//冒泡排序 
int Ascend(int x,int y);//升序 
int Descend(int x,int y);//降序 
void sortWindows(STU* head);
void load_file(STU* head);//读取文件 

int main()
{
	int select = 1;//选择
	STU *head=(STU*)malloc(sizeof(STU));//定义链表头
	head->next = NULL;
    system ("color f0");//白色背景 
	/*交互界面*/
	while (select != 0)
	{
		printf("\n\n");
		printf("***************************************\n");
		printf("**            考试信息管理           **\n");
		printf("**===================================**\n");
		printf("**            1. 成绩录入            **\n");
		printf("**            2. 数据修改            **\n");
		printf("**            3. 数据查询            **\n");
		printf("**            4. 数据删除            **\n");
		printf("**            5. 排    名            **\n");
		printf("**            6. 打    印            **\n");
		printf("**            7. 保    存            **\n");
		printf("**            8. 读    取            **\n");	
		printf("***************************************\n");
		printf("**            0. 退    出            **\n");
		printf("***************************************\n");
		printf("请选择:");
		scanf("%d",&select);
		switch(select){
			case 1:
				Stu_Input(head);
				break;
			case 2:
				change(head);
				break;
			case 3:
				Stu_Search(head); 
				break;
			case 4:
				Stu_delete(head);
				break;
			case 5:
				sortWindows(head);
				break;
			case 6:
				Stu_Output(head);
				break;
			case 7:
				save_file(head);
				break;
			case 8:
				load_file(head);
				break;
			case 0:
				break;
			default:
				break;
		}
	}
	save_file(head);//自动保存功能 
	free_head(head);//释放链表 
	return 0;
}
 
/*输入*/
void Stu_Input(STU* head)
{
	system("cls");//清屏 
	STU* p = (STU*)malloc(sizeof(STU));//申请内存 
	STU* q=NULL;
	if (p == NULL)
	{
		printf("申请内存失败!\n"); return;//申请内存失败则退出程序
	}
	p->next = NULL;//使链表末尾为空
	int j,sum=0,temp;
	char leason[4][maxchar] = { "笔试","一面","二面","综测" };//名字
	char mname[maxchar] = { 0 };//暂存的名字
	char mid[maxid] = { 0 };//暂存的id。
	int mscore[5];//存放各科的成绩
	char msex[3] = { 0 };//性别
	printf("初始化中:");
	for(j=1; j<=4; j++)
	{
		printf(".");
		Sleep(500);
	}
	printf("\n");
	printf("**           成绩录入系统:          **\n"); 
	printf("***************************************\n");
	printf("请输入名字:");
	scanf("%s", mname);
	while (1)
	{
		printf("请输入考号(4位):");
		scanf("%s", mid);
		if (JudgeID(mid) != 0)
		{
			printf("你输入的考号有问题,请重新输入");
		}
		else
		{
			break;
		}
	}
	
	printf("请输入性别:");
	scanf("%s", msex);
	for (j = 0; j < 4; j++)
	{
		printf("请输入%s的成绩:", leason[j]);
		scanf("%d", &mscore[j]);
	}
	/*将暂存的存到链表里*/
	strcpy(p->name, mname);
	strcpy(p->id, mid);
	strcpy(p->sex, msex);
	/*将分数存到链表里*/
	for (j = 0; j < 4; j++)
	{
		p->score[j] = mscore[j];
		sum+=mscore[j];
	}
	p->score[4]=sum;
	q = head->next;
	if (q == NULL)//判断如果链表头为空则存到链表头
	{
		head->next = p;
	}else
	{
		/*找到链表的末尾*/
		while (q->next!=NULL)
		{
			q = q->next;
		}
		q->next = p;
	}
	printf("输入成功!\n");
	printf("是否继续输入?如果是则输入1,不是则输入其他数字.");
	scanf("%d",&temp);
	if(temp==1)
	{
		Stu_Input(head);//                        ****递归函数 
	}else
	{
		return;
	}
}
 
/*输出*/
void Stu_Output(STU *head)
{
	system("cls");//清屏 
	int j;
	STU* q=head->next;
	printf("初始化中:");
	for(j=1; j<=4; j++)
	{
		printf(".");
		Sleep(500);
	}
	printf("\n");
	printf("**              打印系统:           **\n"); 
	printf("***************************************\n");
	printf("\n\n姓名\t性别 考号\t笔试\t一面\t二面\t综测\t总分\t\n");
	while(q)
	{
		printf("%s\t", q->name);
		printf("%-5s", q->sex);
		printf("%-10s\t", q->id);
		q->score[4] = 0;
		for (j = 0; j < 5; j++)
		{
			printf("%d\t", q->score[j]);
			q->score[4] += q->score[j];//计算总成绩 
		}
		printf("\n");
		q = q->next;
	}
	printf("\n");
}
 
/*查找*/
void Stu_Search(STU *head)
{
	system("cls");
	STU* q = head->next;
	char m_id[maxid] = { 0 };//定义考号 
	int j;
	int myflag = 1;//判断当找不到该考生时是否输入
	printf("初始化中:");
	for(j=1; j<=4; j++)
	{
		printf(".");
		Sleep(500);
	}
	printf("\n");
	printf("**              查询系统:           **\n"); 
	printf("***************************************\n");
	printf("请输入你要查找的考号:");
	scanf("%s", m_id);
	printf("\n\n");
	while(q)
	{
		if (strcmp(q->id, m_id) == 0)
		{
			break;
		}
		q = q->next;
	}
	if (q == NULL)
	{
		printf("没找到该考生");
		printf("你要输入吗?1--输入,2--放弃\n");//判断 
		scanf("%d", &myflag);
		if (myflag != 1)
		{
			printf("成功退出!\n");
			return;
		}
		else
		{
			Stu_Input(head);//调用输入函数 
			return;
		}
	}
	printf("该考生的成绩为:\n");
	printf("姓名\t性别 考号\t笔试\t一面\t二面\t综测\t总分\t\n");
	printf("%s\t", q->name);
	printf("%-5s", q->sex);
	printf("%-10s\t", q->id);
	q->score[4] = 0;
	/*计算总分并且存入*/
	for (j = 0; j < 5; j++)
	{
		printf("%d\t", q->score[j]);
		q->score[4] += q->score[j];
	}
	printf("\n");
}
 
/*修改*/
void change(STU *head)
{
	system("cls");
	STU* q = head->next;
	int j;
	int flag = 0;//定义flag反应是否找到该考生
	char m_name[maxchar] = { 0 };
	int  change_score = 0;
	int myflag = 1;//用于判断如果找不到该考生是否输入。
	printf("初始化中:");
	for(j=1; j<=4; j++)
	{
		printf(".");
		Sleep(500);
	}
	printf("\n");
	printf("**              修改系统:           **\n"); 
	printf("***************************************\n");
	printf("请输入你要修改的考生名字:");
	scanf("%s", m_name);
	while(q!=NULL)
	{
		if (strcmp(q->name, m_name) == 0)//字符串匹配函数 
		{
			flag = 1;
			break;
		}
		q = q->next;
	}
	if (flag)
	{
		printf("该考生当前的成绩为:\n");
		printf("姓名\t性别 考号\t笔试\t一面\t二面\t综测\t总分\t\n");
		printf("%s\t", q->name);
		printf("%-5s", q->sex);
		printf("%-10s\t", q->id);
		q->score[4] = 0;
		for (j = 0; j < 5; j++)
		{
			printf("%df\t", q->score[j]);
			q->score[4] += q->score[j];
		}
		printf("\n");
		printf("请输入你要修改的成绩:\n");
		printf("1-笔试,2-一面,3-二面,4-综测\n");
		scanf("%d", &change_score);
		while (change_score)
		{
			switch (change_score)//switch语句分支修改方面 
			{
			case 1:
				printf("请输入你要修改的笔试成绩:");
				scanf("%d", &q->score[0]);
				printf("是否要继续修改,如果是请输入修改科目的序号,否则输入零\n");
				printf("1-笔试,2-一面,3-二面,4-综测\n");
				scanf("%d", &change_score);
				break;
			case 2:
				printf("请输入你要修改的一面成绩:");
				scanf("%d", &q->score[1]);
				printf("是否要继续修改,如果是请输入修改科目的序号,否则输入零\n");
				printf("1-笔试,2-一面,3-二面,4-综测\n");
				scanf("%d", &change_score);
				break;
			case 3:
				printf("请输入你要修改的二面成绩:");
				scanf("%d", &q->score[2]);
				printf("是否要继续修改,如果是请输入修改科目的序号,否则输入零\n");
				printf("1-笔试,2-一面,3-二面,4-综测\n");
				scanf("%d", &change_score);
				break;
			case 4:
				printf("请输入你要修改的综测成绩:");
				scanf("%d", &q->score[3]);
				printf("是否要继续修改,如果是请输入修改科目的序号,否则输入零\n");
				printf("1-笔试,2-一面,3-二面,4-综测\n");
				scanf("%d", &change_score);
				break;
			default:
				printf("你输入的选择有问题,请重新输入:");//对非法输入判断 
				break;
			}
		}
		printf("该考生修改后的成绩为:\n");
		printf("姓名\t性别 考号\t笔试\t一面\t二面\t综测\t总分\t\n");
		printf("%s\t", q->name);
		printf("%-5s", q->sex);
		printf("%-10s\t", q->id);
		q->score[4] = 0;
		for (j = 0; j < 5; j++)
		{
			printf("%d\t", q->score[j]);
			q->score[4] += q->score[j];
		}
		printf("\n");
	}else
	{
		printf("目前没有该考生。\n");
		printf("你要输入吗?1--输入,2--放弃\n");
		scanf("%d", &myflag);
		if (myflag != 1)
		{
			printf("成功退出!\n");
			return;
		}
		else
		{
			Stu_Input(head);
			return;
		}
	}
}
// 预读文件 
void load_file(STU* head)
{
	system("cls");//清屏 
	int j;
	STU* q= head;
	static char file1[] = "./sometext.txt";
	STU temp;
	FILE* fp = fopen(file1,"r");
	
	if(fp == NULL)
	{
		printf("文件打开失败!\n\n");
		return ;
	}
	
	while(q->next != NULL)//找到链表末尾 
	{
		q = q->next;
	}
	
	
	fscanf(fp,"%*[^\n]"); //跳过第一行 
	while(fscanf(fp,"%s %s %s %d %d %d %d %d",temp.name, temp.sex, temp.id, &temp.score[0],
		&temp.score[1], &temp.score[2], &temp.score[3], &temp.score[4]) != EOF)
    {
		STU* p = (STU*)malloc(sizeof(STU));//申请内存 
		strcpy(p->name, temp.name);
		strcpy(p->id, temp.id);
		strcpy(p->sex, temp.sex);
		/*将分数存到链表里*/
		for (j = 0; j <= 4; j++)
		{
			p->score[j] = temp.score[j];
		}
		
		p->next = NULL;
		q->next = p;	
		
		q = q->next;
	}
	fclose(fp);
	printf("文件读取成功!\n");
	return; 
}
/*保存到文件*/
void save_file(STU* head)
{
	system("cls");//清屏 
	int j;
	STU* q= head->next;
	
	FILE* fp;
	fp=fopen("sometext.txt", "wt");
	if (fp == NULL)
	{
		printf("文件打开失败!\n");//程序健壮性 
		return ;
	}
	if (q == NULL)
	{
		printf("无考生信息!\n");//程序健壮性 
		return ;
	} 
	fprintf(fp, "姓名\t性别\t考号\t\t笔试\t一面\t二面\t综测\t总分\t\n");
	while (q != NULL)
	{
		fprintf(fp,"%s\t", q->name);
		fprintf(fp,"%-5s\t", q->sex);
		fprintf(fp,"%-10s\t\t", q->id);
		q->score[4] = 0;
		for (j = 0; j < 5; j++)
		{
			fprintf(fp,"%d\t", q->score[j]);
			q->score[4] += q->score[j];
		}
		fprintf(fp,"\n");
		q = q->next;
	}
	fclose(fp);
	printf("文件保存成功!\n");//提示 
}

/*删除*/
void Stu_delete(STU* head)
{
	system("cls");//清屏 
	int i;
	int myflag;
	STU* q =head;
	STU* p = head->next;
	char mname[maxchar] = {0};
	printf("初始化中:");
	for(i=1; i<=4; i++)
	{
		printf(".");
		Sleep(500);
	}
	printf("\n");
	printf("**              删除系统:           **\n"); 
	printf("***************************************\n");
	printf("请输入你要删除的考生名字:");
	scanf("%s", mname);
	for (; p!=NULL ;p = p->next,q=q->next)//                  ****枚举 
	{
		if (strcmp(p->name, mname) == 0)
		{
			break;
		}
	}
 
	if (p==NULL)
	{
		printf("没有该考生\n");//健壮性提示 
	}else
	{
		printf("该考生的成绩为:\n");
		printf("姓名\t性别 考号\t笔试\t一面\t二面\t综测\t总分\t\n");
		printf("%s\t", p->name);
		printf("%-5s", p->sex);
		printf("%-10s\t", p->id);
		p->score[4] = 0;
		for (i = 0; i < 5; i++)
		{
			printf("%d\t", p->score[i]);
		}
		printf("\n");
		printf("是否删除该考生?1--是,2--否\n");
		scanf("%d", &myflag);
		if (myflag == 1)
		{
			if (p->next==NULL)
			{
				q->next = NULL;;
			}else
			{
				q->next=p->next;
			}
			free(p);
			printf("删除完毕\n");
		}else
		{
			printf("已保留\n");
		}
	}
}
 
/*判断考号输入是否正确*/
int JudgeID(char mid[])
{
	int i;
	for (i = 0; i  < strlen(mid); i++)
	{
		if (mid[i] < '0' || mid[i] > '9')	return 1;
	}
 
	return 0;
}
 
STU* free_head(STU* head)
{
	STU *p=head->next;
	STU *temp=head;
	while(p!=NULL)
	{
		temp=p;
		p=p->next;
		free(temp);//申请后再释放 
	}
	head->next=NULL;
	printf("链表释放完毕!按任意键返回.\n");
	
	return head;
}
int Descend(int x,int y)
{
	if(x<y)
	{
		return 0;
	}else
	{
		return 1;
	}
}
int Ascend(int x,int y)
{
	if(x<y)
	{
		return 1;
	}else
	{
		return 0;
	}
}
void sort(STU *head,int(*cmp)(int,int))
{
	int i;
	printf("初始化中:");
	for(i=1; i<=4; i++)//模拟系统 
	{
		printf(".");
		Sleep(500);
	}
	if(head->next==NULL)//程序的健壮性
	{
		printf("信息为空!\n");
		return;
	}
	if(head->next->next==NULL)//程序的健壮性 
	{
		printf("只有一组信息!\n");
		return; 
	}
 	STU *p1;
 	STU *p2;
 	int temp;//交换 
 	char tempname[maxchar],tempid[maxid],tempsex[3];
 	
 	for (p1=head->next; p1->next!=NULL;p1=p1->next) 
 	{
 		 for (p2=p1->next; p2!=NULL; p2=p2->next)
 		 {
  			if ((*cmp)(p1->score[4],p2->score[4]))
  			{
				for(i=0;i<5;i++)//交换成绩 
				{
					temp=p1->score[i];
					p1->score[i]=p2->score[i];
					p2->score[i]=temp;
				}
				strcpy(tempname,p1->name);//交换名字 
				strcpy(p1->name,p2->name);
				strcpy(p2->name,tempname);
				
				strcpy(tempid,p1->id);//交换考号 
				strcpy(p1->id,p2->id);
				strcpy(p2->id,tempid);
				
				strcpy(tempsex,p1->sex);//交换性别 
				strcpy(p1->sex,p2->sex);
				strcpy(p2->sex,tempsex);
				
   			}
  		}
 	}
 	printf("排名成功!\n");
}
void sortWindows(STU* head)
{
	system("cls");
	int i,select=1; 
	printf("初始化中:");//模拟系统 
	for(i=1; i<=4; i++)
	{
		printf(".");
		Sleep(500);
	}
	printf("\n");
	printf("**              排序系统:           **\n"); //交互式界面 
	printf("***************************************\n");
	printf("**           1. 按总成绩升序排名     **\n");
	printf("**           2. 按总成绩降序排名     **\n");
	printf("**           0. 退出                 **\n");
	printf("***************************************\n");
	while(select!=0)//选择 
	{
		printf("请选择:"); 
		scanf("%d",&select);
		switch(select)
		{
			case 1:
				sort(head,Descend);//调用排序函数 
				break;
			case 2:
				sort(head,Ascend);//应用函数指针 
				break;
			case 0:
				printf("退出成功!\n");
				break;
			default:
				printf("请重新输入:"); //防御性,可重复性 
		}
	}
	return ;
}
posted @ 2022-09-07 16:40  江水为竭  阅读(116)  评论(0编辑  收藏  举报