用C语言实现基础的学生信息管理系统

头文件

#include <stdio.h>
#include<stdlib.h> 

#define FILENAME "student.data"
typedef enum {MAN,WOMAN} SEX; //定义了枚举 

typedef struct tagStudent
{
	int num;        //学生的编号
	char name[20];  //学生的姓名 
	SEX sex;		//学生的性别 
	int age;  		//学生的年龄
	char major[20]; //学生的专业 
	struct tagStudent *next;//指向下一个节点的指针 
}STUDENT,*PSTUDENT;

STUDENT g_head; //头节点 

//声明函数 
//1.显示菜单
void ShowMenu();
//2.获取选择菜单数
int GetMenuChoose();
//3.创建一个节点,他会返回一个新创建的学生节点的指针  
PSTUDENT CreateStudent();
//4.把学生信息节点加入到链表中 
int AddStudent(PSTUDENT pstu);
//5.返回指定编号学生节点的上一个节点的指针 
PSTUDENT GetPrevAddr(int num);
//6.显示所有学生的信息
void ShowAll(); 
//7.显示学生的数量 
int ShowStudentCount();
//8.修改学生信息
void ModityStudent(int num); 
//9.获取用户的选择
int Question(const char *pstr);
//10.获取用户输入的学生的编号
int GetInputNum(); 
//11.删除编号为num的学生信息
void DelStudent(int num);
//12.删除所有的学生信息
void DelAll();
//13.把学生信息保存在文件当中
void SaveToFile();
//14.从文件中读取学生的信息
void LoadFromFile();```

主函数

int main(int argc, char** argv) 
{
	int running = 1;
	while (running)
	{
		switch(GetMenuChoose())
		{
			case 0:
				running = 0;
			break;
			case 1: 
				printf("你选择了菜单1\n"); 
			 	AddStudent(CreateStudent());

			break;
			case 2:
					printf("你选择了菜单2\n");
					DelStudent(GetInputNum()); 
			break;
			case 3:
					printf("你选择了菜单3\n"); 
			break;
			case 4:
					printf("你选择了菜单4\n");
					ModityStudent(GetInputNum());
			break;
			case 5:
					printf("你选择了菜单5\n");
					DelAll(); 
			break;
			case 6:
					printf("你选择了菜单6\n");
					ShowAll(); 
			break;
			case 7:
					printf("你选择了菜单7\n");
					ShowStudentCount(); 
			break;
			case 8:
					printf("你选择了菜单8\n");
					LoadFromFile(); 
			break;
			case 9:
					printf("你选择了菜单9\n");
					SaveToFile(); 
			break;
		}
		system("pause");
	 } 
	return 0;
}   

其他函数

void ShowMenu()
{
	system("cls");//把当前屏幕清空 
	printf("--------------------学生管理系统-----------------\n");
	printf("\n\t1.添加学生信息	2.删除某个学生信息	3.显示某个学生信息\n");
	printf("\t4.修改学生信息	5.删除所有学生信息	6.显示所有学生信息\n");
	printf("\t7.显示信息数量	8.读取文件学生信息	9.保存学生信息至文件\n");
	printf("\t0.退出系统\n");
	printf("\n-----------------------------------------------------------\n");
	

}

int GetMenuChoose()
{
	int num; 
	ShowMenu();
	printf("请选择菜单(0~9):");
	while(1 != scanf("%d",&num)|| num<0||num>9)
	{
		ShowMenu();
		printf("选择菜单错误,请重新选择(0~9):");
		fflush(stdin);//清空输入缓冲区 
	}
	return (num);                                                                                                
}
 
PSTUDENT CreateStudent()
 {
 	int sex;
 	PSTUDENT pstu = (PSTUDENT)malloc(sizeof(STUDENT));//malloc函数返回的是void*类型的指针,所以要强制转为学生信息节点的指针类型 
 	if(!pstu) 
 	{
 		printf("申请内存空间失败!\n");
 		return NULL;
	 }
	 printf("请输入学生的编号(整型):");
	 while(1!=scanf("%d",&pstu->num )||GetPrevAddr(pstu->num)) 
	 {
	 	printf("学生编号输入错误或已经存在,请重新输入学生的编号(整型)");
	 	free(pstu);
		 fflush(stdin); 
	 }
	 printf("请输入学生的姓名(小于20字符):");
	 scanf("%20s",pstu->name );//字符数组不需要取地址了
	 printf("请选择学生的性别(1.男 2.女):"); 
	 while(1 != scanf("%d",&sex)||sex < 1 || sex > 2)
	 {
	 	printf("性别选择错误,请重新选择学生的性别");
	 	fflush(stdin);
	  } 
	  if(1 == sex)
	  	pstu->sex = MAN;
	  else
	    pstu->sex = WOMAN;
	  printf("请输入学生的年龄(10~40):");
	 
	 while(1 !=scanf("%d",&pstu->age)||pstu->age<10||pstu->age>40)
	 {printf("输入年龄有错误,请重新输入:");
	 	fflush(stdin);
	 }
	  printf("请输入学生的专业(小于20字符)");
	  scanf("%20s",pstu->major );
	  pstu->next  = NULL;
	  return pstu; 
	   
	 
  }
//4.把学生信息节点加入到链表中  
  int AddStudent(PSTUDENT pstu)
{
  	PSTUDENT ps = &g_head;
  	if(!pstu)
  	{
  		return 0;
	  }
//判断一下该学生信息是不是已经存在
	if(GetPrevAddr(pstu->num))
	{
		printf("编号为%d的学生信息已经存在!\n",pstu->num);
		free(pstu);//释放该节点内存空间
		return 0; 
	}
//while循环的作用是找到当前链表的最后一个节点 
	 while(ps->next)
	 {
	 	ps = ps->next; 
	  } 
//把新节点加入到最后那个节点的后面 
  	ps->next = pstu;
  	pstu->next = NULL;//把最后一个节点的指针域赋为空 
  	return 1;
  	
 } 
 
 //5.返回指定编号学生节点的上一个节点的指针 
PSTUDENT GetPrevAddr(int num)
{
	PSTUDENT pstu = &g_head;
	while(pstu->next)
	{
		if(pstu->next->num == num)
			return pstu;
		pstu=pstu->next;
	}
	return NULL;
}

//6.显示所有学生的信息
void ShowAll()
{
	PSTUDENT pstu = &g_head;
	printf("--------------------------------------------------------\n"); 
	printf(" 编号      姓名      性别     年龄     专业\n");
	printf("--------------------------------------------------------\n");
	while(pstu->next)
	{
		printf("%d",pstu->next->num);
		printf("      %s",pstu->next->name);
		printf("      %s",pstu->next->sex == MAN ? "男" : "女");
		printf("      %d",pstu->next->age);
		printf("      %s\n",pstu->next->major);
		pstu = pstu->next;//让指针指向下一个节点 
	}
	printf("--------------------------------------------------------\n");
}
//7.显示学生的数量 
int ShowStudentCount()
{
	int count = 0;
	PSTUDENT pstu =&g_head;
	while(pstu->next)
	{
		++count;
		pstu=pstu->next;
	}
	printf("\n当前共有%d位学生信息。\n",count);
	return count;
}

//8.修改学生信息,参数为要修改的学生的编号 
void ModityStudent(int num)
{
	PSTUDENT pstu = GetPrevAddr(num); //获取要修改的学生节点的上一个节点
	int choose;
	if(!pstu)
	{
		printf("没有编号为%d的学生信息",num);
		return; 
	}
	pstu=pstu->next;//将要修改的学生节点的指针改为指向自己的 
	printf("当前学生的姓名为%s,",pstu->name);
	if(Question("确定要修改吗?"))
	{
		printf("请输入学生的姓名(小于20字符):");
		scanf("      %s",pstu->name); 
	 } 
	printf("当前学生的性别为%s",pstu->sex == MAN ? "男":"女");
	if(Question("确定要修改吗?"))
	{
		printf("请输入学生的性别(1.男 2.女):");
		while(1 != scanf("%d",choose)||choose < 1||choose > 2)
		{
			printf("输入错误,请重新输入学生的性别(1.男 2.女)");
			fflush(stdin); 
		}
		if(1 == choose)
			pstu->sex = MAN;
		else
			pstu->sex = WOMAN;
	 }
	printf("当前学生的年龄为%d,",pstu->age);
	if(Question("确定要修改吗?"))
	{
		printf("请输入学生的年龄(10~40):"); 
		while(1 != scanf("%d",pstu->age)||pstu->age<10||pstu->age>40)
		{
			printf("年龄输入错误!请重新输入学生的年龄(10~40):");
			fflush(stdin); 
		}
		
		
		scanf("      %s",pstu->age); 
	 }
	 printf("当前学生的专业为%s,",pstu->major);
	 if(Question("确定要修改吗?"))
	{
		printf("请输入学生的专业(小于20字符):");
		scanf("      %s",pstu->major); 
	 } 
	 printf("修改完毕!\n");	
}
//9.获取用户的选择
int Question(const char *pstr)
{
	char answer;
	printf("%s请选择(y or n):",pstr);
	while(1 !=scanf(" %c",&answer)||(answer !='y'&& answer!='n'))
	{
		printf("输入错误!%s请重新选择(y or n):"); 
		fflush(stdin);//清空输入缓冲区 ,c的库函数 ,c++也可以用 
	}
	if('y' == answer)
		return 1;
	else
		return 0; 
	
	
	
	
	
	
}
//10.获取用户输入的学生的编号
int GetInputNum()
{
	int num;
	printf("请输入学生的编号");
	while(1 != scanf("%d",&num))
	{
		printf("编号输入错误!请重新输入学生的编号(整型)");
		fflush(stdin);
	}
	return num;
}

//11.删除编号为num的学生信息
void DelStudent(int num)
{
	PSTUDENT pstu,ptmp;
	if(pstu =GetPrevAddr(num))
	{
		if(!Question("确定要删除该学生信息吗?"))
		{
			return;
		}
		 ptmp = pstu->next;
		 pstu->next = ptmp->next;
		 free(ptmp);
		 printf("删除了编号为%d的学生信息。\n",num);
	 } 
	 else
	 {
	 	printf("没有找到编号为%d的学生信息。\n",num);
	 }	
}

//12.删除所有的学生信息
void DelAll()
{
	PSTUDENT pstu = g_head.next,ptmp;
	int count = 0;
	if(!Question("确定要删除当前所有的学生信息吗?"))
	{
		return;
	}
	while(pstu)
	{
		ptmp = pstu;
		pstu = pstu->next;
		free(ptmp);
		++count;
	}
	printf("共删除了%d位学生的信息",count);
	g_head.next = NULL;		
}

//13.把学生信息保存在文件当中
void SaveToFile()
{
	FILE *pf = fopen(FILENAME,"wb");
	PSTUDENT pstu = &g_head;
	int i =0,count = ShowStudentCount();
	if(!pf)
	{
		printf("打开代写入的文件失败!\n");
		return;
	}
	if(!Question("确定要将当前学生信息保存到文件中吗?"))
	{
		fclose(pf);
		return;
	}
	fwrite(&count, 1 , sizeof(count), pf);//把学生信息的数量先写入到文件的里头
	while(pstu->next)
	{
		fwrite(pstu->next, 1 ,sizeof(STUDENT), pf);//把每位学生信息写入文件
		++i;
		pstu = pstu->next; 
	 }
	fclose(pf);
	if(i == count)
	{
		printf("成功的写入了%d条学生的信息。\n",count);
	 } 
	 else
	 {
	 	printf("应写入%d条学生信息,实际写入%d条学生信息",count,i);
	 }	
}

//14.从文件中读取学生的信息
void LoadFromFile()
{
	int i,count = 0, repeat = 0;
	FILE *pf;
	PSTUDENT pstu;
	printf("提示: 从文件中读取学生信息会询问是否清空当前学生信息(不清空表示合并所有信息)。\n");
	if((pf = fopen(FILENAME,"rb"))  == NULL)
	{
		printf("文件还没有创建,请手工输入学生信息并保存吧!\n");
		return;
	}
	DelAll();//删除之前的所有信息,然后从文件中读取
	fread(&count, 1 ,sizeof(count), pf);//获取学生信息的数量
	for(i = 0; i< count ;++i)
	{
		pstu = (PSTUDENT)malloc(sizeof(STUDENT));
		fread(pstu, 1 , sizeof(STUDENT) ,pf);
		if(!AddStudent(pstu))
		{
			++repeat;//保存有多少个和当前链表中相重复的学生信息 
		}
	 } 
	 fclose(pf);
	 printf("文件读取完毕!新增学生信息%d条。\n",count - repeat); 
	 }
	```
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值