2018年C语言大作业之学生信息管理系统

2018年C语言大作业之学生信息管理系统

某末流211大学计算机类专业。
大一上的C语言课,大一下暑假前的小学期做的实验。
之前对链表只是大致了解,打ACM也用的很少,经过这次实验,还是深入地了解了链表文件输入输出的应用。
原理都不难,直接贴代码了,仔细看一看应该是可以看懂的,希望参考的同学还是自己动手画一画链表链接、删除等操作,真的是理解和掌握链表的捷径。
我们老师要求做成三个cpp文件,分别是主函数部分自定义函数的声明自定义函数,仔细看看不难看懂,合并到一个cpp里也不难,大家可以自行发挥。

第一部分:主函数

#include
#include
#include
#include 
#define len sizeof(struct student)
#include"声明.cpp"
#include"自定义函数.cpp"
//主函数	
int main()
{
	char s[15];
	struct student *head; 
	while(1)
	{
		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("9.删除某个班级、某门课程的成绩小于某个分数的学生\n");
		printf("10.按照姓名排序\n");
		printf("11.保存当前信息\n");
		printf("其他,推出系统\n");
		int x,z;
		char y[10];
		struct student *h,*k;
		scanf("%d",&x);
		switch(x)
		{
			case(1):
				h=input();
				save(h);
				break;
			case(2):
				printf("请输入要查找的文件名:\n");
				getchar();
				gets(s);
				head=creatlist(s);
				printf("\n");
				printf("注册链表成功\n"); 
				break;
			case(3):
				printf("请输入要删除的学生的学号:\n");
				scanf("%s",y);
				head=del(head,y);
				break;
			case(4):
				printf("请按顺序输入要插入的信息,用空格隔开\n");
				insert(head);
				print(head);
				break;
			case(5):
				printf("当前信息如下:\n");
				print(head);
				break; 
			case(6):
				printf("总成绩最高的学生信息如下\n");
				printf("\n学号\t姓名\t专业  \t\t班级   成绩0   成绩1   成绩2   \t\n"); 
				outone(MAX(head));
				break;
			case(7):
				printf("按学号查找请按0,按姓名查找请按1:\n");
				scanf("%d",&z);
				if(z==0)
				{
					head=numfind(head);
					print(head);
				}
				if(z==1)
				{
					head=namefind(head);
					print(head);
				}
				if(z!=0&&z!=1)
					printf("请按要求输入!!!!!\n");
				break;
			case(8):
				head=search_major_score(head);
				print(head);
				break;
			case(9):
				head=del_class_score(head);
				print(head);
				break;
			case(10):
				namesort(head);
				print(head);
				break;
			case(11):
				save(head);
				break;
			default:
				break;
		}
	}
	return 0;
}

第二部分:自定义函数声明

//定义结构体 
struct student{
		char num[10];//学号
		char name[15];//姓名 
		char major[10];//专业computer,softwear,network
		int classNo;//班级 
		int score[3];//3门课的成绩  
		int sum;//3门课的总成绩 
		struct student *next;//指针	88u
	};
//定义全局变量
int n;int a;
//函数声明
struct student *input();
struct student *creatlist(char *filename);
void save(student *head);
void print(struct student*head);
struct student *del(struct student *head,char z[]);
struct student *insert(struct student*head);
void outone(struct student *temp);
struct student *MAX(struct student*head);
struct student *numfind(struct student *head);
struct student *namefind(struct student *head);
struct student *search_major_score(struct student *head);
struct student *del_class_score(struct student *head);
void namesort(struct student *head);

第三部分:自定义函数

//输入学生信息 
struct student *input()
{
	n=0;
	printf("请输入学生人数\n");
	scanf("%d",&a);
	printf("请录入这%d名学生的信息:\n",a);
	struct student *head;
	struct student *p1,*p2;
	head=(struct student*)malloc(len);
	while(n<a)
	{
		p1=(struct student*)malloc(len);
		scanf("%s%s%s%d%d%d%d",&p1->num,&p1->name,&p1->major,&p1->classNo,&p1->score[0],&p1->score[1],&p1->score[2]);
		p1->sum=0;
		p1->sum=p1->score[0]+p1->score[1]+p1->score[2];//计算分数之和 
		n++;
		if(n==1)//特判第一波 
			head->next=p1;
		else
			p2->next=p1;
		p2=p1;
	}
	p2->next=NULL;//注意最后附空值 
	return(head);
} 
//从文件中读取学生信息,并建立链表
struct student *creatlist(char *filename)
{
	student *s,*p,*head;               //s为当前节点 ,head为头节点
	FILE *fp;
	if((fp=fopen(filename,"rb"))==NULL)
	{
		printf("Wrong.");
		exit(0);
	}
	head=(student *)malloc(sizeof(student)); //开辟内存 
	s=(student *)malloc(sizeof(student));    //开辟内存
	if((fread(s,sizeof(student),1,fp))==NULL)
	{
		printf("Wrong.");
		exit(0);
	} 
	head->next=s;
	p=s;
	while(s->next!=NULL)
	{
		s=(student *)malloc(sizeof(student));
		fread(s,sizeof(student),1,fp);//读取数据 
		p->next=s;//赋值 
		p=s;
	}
	return head;
}
//保存数据文件
void save(student *head)
{
	struct student *p;
	p=head->next;//从第二个开始保存
	FILE *fp;
	char filename[15];
	printf("请输入要建立的文件的名称:\n"); 
	scanf("%s",&filename);
	if((fp=fopen(filename,"wb"))==NULL)
	{
		printf("Wrong.");
		exit(0);
	}	
	while(p!=NULL)
	{
		if(fwrite(p,sizeof(student),1,fp)!=1)
		{
			printf("写入文件失败\n"); 
		}
		p=p->next;
	}
	printf("写入文件成功!\n"); 
	fclose(fp);
} 
//打印有头节点 
void print(struct student*head)
{
	struct student *p;
	printf("\n学号\t姓名\t专业  \t\t班级   成绩0   成绩1   成绩2   \t"); 
	p=head->next;//从第二个开始打印 
	while(p!=NULL)
	{
		printf("\n%s\t%-6s\t%-10s\t%d\t%d\t%d\t%d\t", p->num, p->name, p->major,p->classNo,p->score[0],p->score[1],p->score[2]);
		p=p->next;//循环 
	}
	printf("\n");
}
//按学号删除学生信息 
struct student *del(struct student *head,char z[])
{
	struct student *p,*q,*k;
	q=head;
	p=head->next;//q为前置节点,p为当前节点 
	int w=atoi(z),e=atoi(p->num);//字符转整形 
	if(head==NULL)
		printf("Wrong.\n");
	while(w!=e&&p->next!=NULL)//判断是否符合条件 
	{
		q=q->next;
		p=p->next;
		e=atoi(p->num);
	}
	if(w==e)//停止原因1:符合条件 
	{
		printf("被删除的学生的信息是:\n");
		printf("\n学号\t姓名\t专业  \t\t班级   成绩0   成绩1   成绩2   \t\n"); 
		outone(p);
		printf("\n");
		printf("确定要删除此人信息?输入'1'确认删除,输入'0'取消删除:\n");
		int y;
		scanf("%d",&y);
		if(y==1)
		{
			q->next=p->next;//跳过该节点,链接下一节点 
			printf("删除成功!\n");
			printf("新的学生信息如下:\n");
			print(head);
		}
		if(y==0)
		{
			printf("取消删除成功!\n");
		}
	}
	else//停止原因2:查无此人 
	{
		printf("很抱歉,系统查无此人\n"); 
	}
	return(head);
}
//按学号插入学生信息 
struct student *insert(struct student*head)
{
	struct student *temp;
	struct student *p;
	temp=(student *)malloc(sizeof(student));
	p=head;
	printf("\n学号\t姓名\t专业  \t\t班级   成绩0   成绩1   成绩2   \t\n"); 
	scanf("%s%s%s%d%d%d%d",&temp->num,&temp->name,&temp->major,&temp->classNo,&temp->score[0],&temp->score[1],&temp->score[2]);
	temp->sum=temp->score[0]+temp->score[1]+temp->score[2];//注意计算分数总和 
	while(p!=NULL)
	{
		int g=atoi(p->next->num);int b=atoi(temp->num);//字符转化整形 
		if(g>b)//判断:符合条件进行插入 
		{
			temp->next=p->next;
			p->next=temp;
			break;
		}
		else//不符合条件后移一位 
		{
			p=p->next;
			g=atoi(p->next->num);
			if(p->next==NULL)//特判,否则出错 
			{
				p->next=temp;
				temp->next=NULL;
				break;
			}
		}
	}
	return(head);
}
//输出一个节点信息
void outone(struct student *temp)
{
	printf("%s\t%-6s\t%-10s\t%d\t%d\t%d\t%d\t\n", temp->num, temp->name, temp->major,temp->classNo,temp->score[0],temp->score[1],temp->score[2]);
}
//寻找成绩最高的学生 
struct student *MAX(struct student*head)
{
	struct student *p,*maxn;
	p=head;
	int big=p->sum;//big记录当前最大值 
	maxn=p;
	while(p!=NULL&&p->next!=NULL)//遍历一遍,找到分数最大节点 
	{
		p=p->next;
		if(p->sum>=big)//与big值比较 
		{
			big=p->sum;
			maxn=p;
		}
	}
	return(maxn);
}
//寻找指定学号的学生并修改该学生信息 
struct student *numfind(struct student *head)
{
	int flag=0; 
	char x[15];
	printf("请输入学号:\n");
	scanf("%s",x);
	struct student *p;
	p=head;
	while(p!=NULL)
	{
		if(strcmp(p->num,x)==0)//字符串比较函数判断学号是否相同 
		{
			printf("请按以下顺序修改该学生信息"); 
			printf("\n学号\t姓名\t专业  \t\t班级   成绩0   成绩1   成绩2   \t\n"); 
			scanf("%s%s%s%d%d%d%d",&p->num,p->name,p->major,&p->classNo,&p->score[0],&p->score[1],&p->score[2]);//重新修改 
			flag++;
			break;
		}
		p=p->next;
	}
	if(flag!=0)//flag特判 
		printf("修改成功!新信息如下:\n");
	else
		printf("抱歉,系统查无此人!\n");
	return(head);
}
//寻找指定姓名的学生并修改学生信息
struct student *namefind(struct student *head)
{
	int flag=0; 
	char x[15];
	printf("请输入姓名:\n");
	scanf("%s",x);
	struct student *p;
	p=head;
	while(p!=NULL)
	{
		if(strcmp(p->name,x)==0)//字符串比较函数查姓名 
		{
			printf("请按以下顺序修改该学生信息"); 
			printf("\n学号\t姓名\t专业  \t\t班级   成绩0   成绩1   成绩2   \t\n"); 
			scanf("%s%s%s%d%d%d%d",&p->num,p->name,p->major,&p->classNo,&p->score[0],&p->score[1],&p->score[2]);//重新修改 
			flag++;
			break;
		}
		p=p->next;
	}
	if(flag!=0)//flag特判 
		printf("修改成功!新信息如下:\n");
	else
		printf("抱歉,系统查无此人!\n");
	return(head);
}
//查找某个专业、某门课程的成绩小于某个分数的学生
struct student *search_major_score(struct student *head)
{
	struct student *p,*q,*xin,stu1;
	q=(student *)malloc(sizeof(student));//新开辟内存,建立新链表 
	xin=q;
	p=head;
	char a[15];
	int x,i;
	printf("请输入专业:"); 
	scanf("%s",a);
	printf("请输入课程编号(0-2):");
	scanf("%d",&i);
	printf("请输入分数:");
	scanf("%d",&x);
	while(p!=NULL)
	{
		if(strcmp(p->major,a)==0)
		{
			if(p->score[i]<x)
			{
				q->next=(student *)malloc(sizeof(student));	//开辟内存,新存数据 
				q=q->next;	//注意建立带头节点的链表 
				strcpy(q->num,p->num);strcpy(q->major,p->major);strcpy(q->name,p->name);
				q->score[0]=p->score[0];q->score[1]=p->score[1];
				q->score[2]=p->score[2];q->sum=p->sum;q->classNo=p->classNo;
			}
		}
		p=p->next;
	}
	q->next=NULL;//注意最后附空值 
	return(xin);
}
//删除某个班级、某门课程的成绩小于某个分数的学生
struct student *del_class_score(struct student *head)
{
	struct student *p,*q;
	q=head;
	p=head->next;
	int a,i,x;
	printf("请输入班级:"); 
	scanf("%d",&a);
	printf("请输入课程编号(0-2):");
	scanf("%d",&i);
	printf("请输入分数:");
	scanf("%d",&x);
	while(p!=NULL)
	{
		if(p->classNo==a&&p->score[i]<x)
		{
			q->next=p->next;//符合条件,跳过该节点进行删除 
			p=q->next;//注意不要忘记p要重新换位置 
		}
		else//不符合条件,pq一起后移一位 
		{
			p=p->next;
			q=q->next;			
		}

	}
	q=NULL;//最后附空值 
	return(head);
}
//按照姓名排序
void namesort(struct student *head)
{
	struct student *front,*min,*rear,*p,*count;
	int j=0;
	count=head;
	while(count!=NULL)
	{
		j++;//计数器记录共有多少学生的信息 
		count=count->next;
	}
	min=head->next;
	p=head->next;
	rear=head;//rear为前置节点 
	for(int i=0;i<j-1;i++)//第一次循环,找最值 
	{
		while(p)//第二次循环进行比较 
		{
			if(!p->next)//特判,否则会出错 
			{
				p=p->next;
				continue;
			}
			if(strcmp(p->next->name,min->name)<0)//字符串比较函数 
			{
				min=p->next;//移动变换 
				front=p;
			}
			p=p->next;//下一个节点 
		}
		if(min==rear->next)//如果循环一圈,没有找到新的最大值 
		{
			rear=min;
			min=min->next;
			p=min;
		}
		else//循环一圈,有新的最大值 
		{
			front->next=min->next;
			min->next=rear->next;
			rear->next=min;
			rear=min;
			min=min->next;
			p=min;
			front=p; 
		}
	}
}


你可能感兴趣的:(C语言,数据结构实验作业)