新版-C语言学生信息管理系统


拥有基本的学生信息系统的功能, 功能点如下所示:
1.添加学生信息
2.修改学生信息
3.删除学生信息
4.查看学生信息
5.搜索学生信息
6.查看系统学生总人数
7.学生信息排序
8.保存学生信息(保存在D:/students.txt)
9.导入学生信息(导入D:/students.txt文件中的信息)

主界面

在这里插入图片描述

1.添加学生信息

在这里插入图片描述
在这里插入图片描述

2.修改学生信息

3.删除学生信息

4.查看学生信息

在这里插入图片描述

5.搜索学生信息

在这里插入图片描述

6.查看系统学生总人数

在这里插入图片描述

7.学生信息排序

8.保存学生信息(保存在D:/students.txt)

在这里插入图片描述

9.导入学生信息(导入D:/students.txt文件中的信息)

学生信息管理系统代码


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<windows.h>

struct Student {
	int id; //学号 
	char name[20]; //名字 
	int sex; //性别 0为女,1为男 
	char specialized[25]; //学生的专业 
	char date[25]; //出生日期 
	char address[255]; //学生住址 
	float score; //学生分数 
	//Stu -> Stu -> Stu -> Stu -> NULL 
	struct Student *next; //链表的构成,指向下一个结构体
	/*struct student *next 是
	申请了一个 struct student
	这结构体类型的指针
	*/
};

//学生管理系统中的总人数数量  
int total_count = 0;

//重定义 struct Student 为 Stu(起别名) ,后续可以直接使用Stu代替 struct Student 
typedef struct Student Stu;


//主菜单 
void mainMenu()
{
	printf("	 0.退出\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("	 ******请选择:");
}

 //退出程序 
void exitProgram()
{
	system("cls");
	system ("color 04");
	int i, j, k, l, m;
	char c=3; //ASCII码里面 3 就是一个字符小爱心
	for (i=1; i<=5; i++) printf("\n"); //开头空出5行
	for (i=1; i<=3; i++) 
	{ //前3行中间有空隙分开来写
		for (j=1; j<=32-2*i; j++) printf(" "); //左边的空格,每下一行左边的空格比上一行少2个 //8*n-2*i
		for (k=1; k<=4*i+1; k++) printf("%c", c);//输出左半部分字符小爱心
		for (l=1; l<=13-4*i; l++) printf(" "); //中间的空格,每下一行的空格比上一行少4个
		for (m=1; m<=4*i+1; m++) printf("%c", c);//输出右半部分字符小爱心
		printf("\n"); //每一行输出完毕换行
	}
	for (i=1; i<=3; i++) 
	{ //下3行中间没有空格
		for (j=1; j<=24+1; j++)  printf(" "); //左边的空格 //8*(n-1)+1
		for (k=1; k<=27; k++) 
		if (k==8)
		printf("谢");
		else if (k==10)
		printf("谢");
		else if (k==12)
		printf("使");
		else if (k==14)
		printf("用");
		else
		printf("%c", c);//输出字符小爱心
		printf("\n"); //每一行输出完毕换行
	}
	for (i=7; i>=1; i--)
	{ //下7行
		for (j=1; j<=40-2*i; j++) printf(" "); //左边的空格,每下一行左边的空格比上一行少2个//8*(n+1)-2*i
		for (k=1; k<=4*i-1; k++) printf("%c", c);//每下一行的字符小爱心比上一行少4个(这个循环是i--)
		printf("\n"); //每一行输出完毕换行
	}
	for (i=1; i<=39; i++)printf(" "); //最后一行左边的空格
	printf("%c\n", c); //最后一个字符小爱心
	for (i=1; i<=5; i++)printf("\n"); //最后空出5行
}


//添加学生 
void addStudent(Stu *head) 
{
	//清空屏幕 
	system("cls");
	//找到最后一个节点,然后才能添加
	//最后一个节点的 next 为 NULL 
	//Stu->Stu->Stu->NULL 
	while(head != NULL && head->next!=NULL)//遍历,很重要,是结点,连接着接下来输入的数据与上一个数据。
	{
		head = head->next;//head->next==NULL;找到存放指针为空的结构体,找到尾结点。 
	}
	printf("请输入学生个数: ");
	int num;
	scanf("%d",&num);
	
	int i=1;
	for(; i<= num; i++){
		printf("请输入第%d个学生信息\n",i);
		Stu *stu;//开辟一个单独结构体,字母任意。 
		stu=(Stu *)malloc(sizeof(Stu));//开辟内存
		/*
		malloc函数只是开辟一块区域/
		//calloc函数与malloc 函数的区别仅在于一次可以分配n块区域。 
		用变量表示长度,想对数组的大小作动态说明,这是错误的。
		但是在实际的编程中,往往会发生这种情况,
		即所需的内存空间取决于实际输入的数据,而无法预先确定。
		对于这种问题,用数组的办法很难解决。为了解决上述问题,
		C语言提供了一些内存管理函数,
		这些内存管理函数可以按需要动态地分配内存空间,
		也可把不再使用的空间回收待用,
		为有效地利用内存资源提供了手段。
		*/ 
		printf("学号:");
		scanf("%d",&stu->id);
		printf("学生姓名: ");
		scanf("%s",stu->name);
		printf("性别:");
		scanf("%d",&stu->sex);
		printf("专业:");
		scanf("%s",stu->specialized);
		printf("出生日期:");
		scanf("%s",stu->date);
		printf("家庭住址:");
		scanf("%s",stu->address);
		printf("总成绩:");
		scanf("%f",&stu->score);
		stu->next=NULL;//结构体的存地址的地方初始化 //结构体初始化。。 
		head->next=stu;//连接链表 
		//head指向最后一个节点,刚刚给stu添加到节点后面了,所以限制stu就是最后一个节点
		//我们让head指向stu,此时head依旧指向最后一个节点上了 
		head=stu;
		system("cls");
	}
	
	total_count += num; //+= --> total_count = total_count + num; 
	
	printf("信息录入成功!!!\n");
	system("pause");
	system("cls");
	/*
	system("pause")作用: 
	让操作系统来暂停该程序进程的执行,
	同时程序运行到此语句处时,
	会在程序的窗口上显示“Press any key to continue . . .”
	 也就是 “按任意键继续...”,
	 即等待用户按下任意一个按键使该程序从暂停状态
	返回到执行状态继续从刚才暂停的地方开始执行。
	*/ 
	/*system("cls")就是执行命令“清屏”的意思。*/ 
}
//打印所有学生信息 
void printAllStudents(Stu *q) 
{
	system("cls");
	while(q->next!=NULL)
	{
		q=q->next;/// 数据从第二个开始存,应该从第二个进行查找。 
		printf("学号:%d\n",q->id);
		printf("姓名:%s\n",q->name);
		printf("性别:%s\n",q->sex == 0 ? "女" : "男");
		printf("专业:%s\n",q->specialized);
		printf("出生日期:%s\n",q->date);
		printf("家庭地址:%s\n",q->address);
		printf("总成绩:%.2f\n",q->score);
		printf("\n");
	}
	system("pause");
	system("cls");
	return;
}

//删除学生信息 
void deleteStudent(Stu *head) 
{
	system("cls");
	Stu *prev = head; //用于删除节点,记录上一个节点 
	head = head->next;//存数据从第二个开始存,应该从第二个进行查找。
	printf("请输入删除的人的姓名:");
	char name[20];
	scanf("%s",name);
	//用于判断是否找到输入名字的学生 
	int num = 0;
	
	
	//一直找到head为NULL,匹配了就删除退出循环 
	while(head != NULL)
	{
		//存数据从第二个开始存,应该从第二个进行查找。  
		if(strcmp(head->name,name)==0){
			num = 1;
			//匹配到name相同的节点 
			//删除head节点 
			//删除前: prev->head->xxx->xxx->NULL;
			//删除后: prev->xxx->xxx->NULL;
			//将指向删除的地址和后一个地址连接,跳过删除对象。 
			prev->next=head->next;
			
			free(head); //清空内存 
			head = NULL; //置为空,防止后续被调用 
			/*
			 清空数据,结构体空间还在。
			  free后只是做了个标记,告诉系统这块内存不用了,
			  一旦调用后, 那个地址是不被保护的,
			  也就是说其他的变量随时可能占用那个地址。*/ 
			break;
		 }
		prev = prev->next;
		head = head->next;
	}
	if(num != 1)
	{
		printf("删除失败\n");
	}
	else 
	{
		printf("删除成功\n");
		total_count -= 1;
	}
}

//搜索学生信息 
void searchStudent(Stu *q)
{
	system("cls");
	printf("请输入查找人姓名:");
	char name[20];
	scanf("%s",name);
	int num = 0;
	//第二个开始存储的学生信息,从第二个节点开始查找 
	q=q->next;
	while(q!=NULL){
		if(strcmp(q->name,name)==0){
			num = 1;
			system("cls");//清空屏幕 
			printf("\n\n查找完成\n\n");
			printf("学号:%d\n",q->id);
			printf("姓名:%s\n",q->name);
			printf("性别:%s\n",q->sex == 0 ? "女" : "男");
			printf("专业:%s\n",q->specialized);
			printf("出生日期:%s\n",q->date);
			printf("家庭地址:%s\n",q->address);
			printf("总成绩:%.2f\n",q->score);
		}
		q=q->next;
	}
	if(num == 0)
	{
		printf("\n\n查无此人\n\n");
	}
	system("pause");
	system("cls");
}

//交换两个节点的信息 
void swapStudent(Stu *prev,Stu *head)
{
	int t1;
	t1=prev->id;
	prev->id=head->id;
	head->id=t1;
	
	char t2[20];
	strcpy(t2,prev->name);
	strcpy(prev->name,head->name);
	strcpy(head->name,t2);
	
	int t3;
	t3 = prev->sex;
	prev->sex = head->sex;
	head->sex = t3;
	
	char t4[20];
	strcpy(t4,prev->specialized);
	strcpy(prev->specialized,head->specialized);
	strcpy(head->specialized,t4);
	
	char t5[20];
	strcpy(t5,prev->date);
	strcpy(prev->date,head->date);
	strcpy(head->date,t5);
	
	char t6[20];
	strcpy(t6,prev->address);
	strcpy(prev->address,head->address);
	strcpy(head->address,t6);
	
	float t7;
	t7=prev->score;
	prev->score = head->score;
	head->score=t7;
}

//学生排序,按照分数从大到小排序 
void sortStudents(Stu *head)
{
	//系统中人数小于2就无需排序 
	if(total_count<2)
	{
		printf("\n\n数据过少,不进行排序!\n\n");
		system("pause");
		system("cls");
		return;
	}
	
	system("cls");
	printf("请输入成绩排序规则:\n");
	printf("输入0按照成绩从小到大排序\n");
	printf("输入1按照成绩从大到小排序\n");
	int op;
	scanf("%d",&op);
	
	head = head->next;//head指向的是链表的第三个节点,第二个有效节点 
	
	
	Stu *pFirst = NULL, *pSecond = NULL, *pEnd = NULL; 
	pFirst = head;
	pSecond = head;
	
	while(pFirst != pEnd)
	{
		while(pFirst->next != pEnd)
		{
			if(op == 0)
			{
				//从小到大排序 
				if(pFirst->score > pFirst->next->score)
				{
					//交换两个节点的信息 
					swapStudent(pFirst,pFirst->next);
				}
			}
			else
			{
				//从大到小排序
				if(pFirst->score < pFirst->next->score)
				{
					//交换两个节点的信息 
					swapStudent(pFirst,pFirst->next);
				}
			}
			pFirst = pFirst->next;
		}
		//此时pFirst是链表中的最后一个节点了 
		pEnd = pFirst;
		pFirst = head;
	}
	printf("\n\n排序成功!!!\n\n");
	system("pause");
	system("cls");
}

//修改学生信息 
void updateStudent(Stu *head)
{
	system("cls");
	//从第二个节点开始查找 
	Stu *q=head->next;
	printf("请输入修改人姓名:");
	char name[20];
	scanf("%s",name);
	while(q != NULL){
		if(strcmp(q->name,name)==0)
		{
			printf("\n\n存在该学生信息!\n\n");
			
			printf("请输入要修改的学生学号:");
			scanf("%d",&q->id);
			printf("请输入要修改的学生姓名:");
			scanf("%s",q->name);
			printf("请输入要修改的学生性别:");
			scanf("%d",&q->sex); 
			printf("请输入要修改的学生专业:");
			scanf("%s",q->specialized);
			printf("请输入要修改的学生出生日期:"); 
			scanf("%s",q->date);
			printf("请输入要修改的学生家庭地址:");
			scanf("%s",q->address); 
			printf("请输入要修改的学生的总成绩:");
			scanf("%f",&q->score);
			printf("\n\n修改成功!!!\n\n");
			break;
		}
		q=q->next;
	}
	if(q==NULL)
	{
		printf("\n\n不存在该学生信息\n\n\n");
	}
}

//保存所有学生信息 
void saveStudents(Stu *q)
{
	system("cls");
	FILE * fp = fopen("D:\\students.txt", "a");
	if(fp == NULL)
	{
		printf("打开文件失败!!!\n\n");
		return;
	}
	while(q->next!=NULL)
	{
		q=q->next;
		fprintf(fp, "%d %s %d %s %s %s %f\n",q->id,q->name,q->sex,q->specialized,q->date,q->address,q->score);
		/*fprintf函数作用:传送格式化输出到一个文件中
		*/
	}
	fclose(fp);
	printf("\n\n文件保存成功!!!\n\n\n");
}

//导入学生信息到链表的最后 
void importStudents(Stu *head)
{
	system("cls");
	
	FILE *fp=fopen("D:\\students.txt","r"); 
	if(fp==NULL)
	{
		printf("打开文件失败\n");
		return;
	}
	
    while(head->next!=NULL)
    {
    	head = head->next;
	}
	
	int num = 0;
    char buf[1024];
 
    while (fgets(buf, sizeof(buf), fp) != NULL)
    {
		Stu *q=(Stu*)malloc(sizeof(Stu));
		q->next=NULL;
		printf("%s", buf);
        //格式化输入 
		sscanf(buf, "%d %s %d %s %s %s %f\n",&q->id,q->name,&q->sex,q->specialized,q->date,q->address,&q->score);
		
		head->next=q;
		head = q;
		num++;
    }
	 
	fclose(fp); 
	
	if(num != 1)
	{
		total_count += num;
		printf("导入成功\n");
	}
	else
	{
		printf("无数据"); 
	}
}
				
int main()
{
	//开辟一个空的头节点 
	Stu *head;
	head=(Stu *)malloc(sizeof(Stu));
	head->next=NULL;
	system("cls"); //清空控制台 
	system("color 06"); //控制台设置颜色 
	
	//进来之后死循环,展示菜单,等待用户输入 
	while(1)
	{
		mainMenu();
		int op;
		scanf("%d",&op);
		switch(op)
		{
			case 0:
			{
				//退出程序 
				exitProgram();
				printf("\n\n\n    	 谢谢使用【手动微笑】\n\n");
				return 0;				
			}
			case 1:
			{
				//添加学生信息 
				addStudent(head);
				break;
			}
			case 2:
			{
				//修改学生信息 
				updateStudent(head);
				system("pause");
				system("cls");
				break;
			}
			case 3:
			{
				//删除学生信息 
				deleteStudent(head);
				system("pause");
				system("cls");
				break;
				
			}
			case 4:
			{
				//打印所有学生信息 
				printAllStudents(head);
				break;	
			}
			case 5:
			{
				//搜索学生信息 
				searchStudent(head);
				break;	
			}
			case 6:
			{
				printf("\n\n总人数为:%d\n\n\n",total_count);
				system("pause");
				system("cls");
				break;	
			}
			case 7:
			{
				//学生排序,按照分数从大到小排序 
				sortStudents(head);
				break;	
			}
			case 8:
			{
				//保存所有学生信息 
				saveStudents(head);
				system("pause");
				system("cls");
				break;	
			}
			case 9:
			{
				//导入学生信息到链表的最后 
				importStudents(head);
				system("pause");
				system("cls");
				break;
			}
			default:
			{
				printf("\n\n您的输入有误!!!请重新输入\n");
				system("pause");
				system("cls");
				break;	
			}
		}
	}
} 




  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值