班级档案管理系统(C语言)

96df6d1819794ebc86ebf5495df5d1b1.jpeg

这是本人基本学完C语言时做的一个课程设计,希望能够帮到大家(设计要求如上图片)。

怎么说呢?这个也是我第一次写课程设计,准确来说,对于第一次确实时有难度的。

现在我要分享我写这个课程设计的一些心得分享给大家。

第一步:首先我们一拿到需求,肯定是要先想好这个题目的一些需求思路,并且做出一个思维导图肯定是更好的。

其实做出了思维导图,我们只需要按着一个一个的需求来写相关代码,就不会觉得难度那么大了。这也算是用到了大化小的一个逻辑思维了(我记得这个方法好像是有个名字的,但是我现在不太记得了)。

话不多说,我们直接上思维导图:

82f51a73c2cc4ffdbff91563ea38b267.jpeg

 现在我们已经有思维导图了,那么直接不用多说了(其实我感觉算是思路还是比较清晰的哈)。

我们现在需要做的第一步,那就是学生的基本信息的录入。

那么这个时候,我们有面临的问题就是:如何存储学生的基本信息

我们有两种选择:一种是利用结构体数组,另外一种就是用链表(链表相对于数组来说是难度较大的)。

这里我做的时候,是选择了用链表,因为考虑到我们后面还有删除,修改的操作,用数组来说,这里的操作就不如链表便捷了。

第二步:那就是写代码啦!

①.我们直接上代码:(这一段代码我们是对学生信息的基本录入)

struct Student* pEnd, *pNew;
 struct Student* pHead=NULL;
 
 int iCount;//全局变量来表示链表长度
 struct Student* Create()//我们创建一个链表,来录入信息 
 {
 	/*struct Student* pHead=NULL;//初始化链表头指针为空 
 	struct Student* pEnd, *pNew;*/
 	iCount=0;//初始化链表长度;
	pEnd=pNew=(struct Student*)malloc(sizeof(struct Student));
//	printf("请输入学生信息:\n");
	scanf("%ld", &pNew->num);
	scanf("%s", &pNew->name);
	scanf("%s", &pNew->sex);
	scanf("%d", &pNew->birthday.year);
	scanf("%d", &pNew->birthday.month);
	scanf("%d", &pNew->birthday.day);
	scanf("%s", &pNew->bz);
	while(1/*pNew->num!=0*/)//如果学号为零,就停止输入; 
	{
		iCount++;//iCount自增,表示链表中节点增加,同时也表示,学生的人数; 
		if(iCount==1)
		{
			pNew->pNext=pHead;//使得头指针为空; 
			pEnd=pNew;//跟踪加入新的节点 ; 
			pHead=pNew;//头指针指向首节点 ; 
		}
		else
		{
			pNew->pNext=NULL;//新节点的指针头为空 
			pEnd->pNext=pNew;//原来的尾节点指向新的节点 
			pEnd=pNew;	//pEnd指向新的节点 
		} 
		pNew=(struct Student*)malloc(sizeof(struct Student));//在此分配节点内存空间
		scanf("%ld", &pNew->num);
		scanf("%s", &pNew->name);
		scanf("%s", &pNew->sex);
		scanf("%d", &pNew->birthday.year);
		scanf("%d", &pNew->birthday.month);
		scanf("%d", &pNew->birthday.day);  
		//scanf("%d", &pNew->age=2022-pNew->birthday.year);
		scanf("%s", &pNew->bz);
		//printf("%d",pNew->num);
		if(pNew->num==0)
		{
			printf("录入成功!\n"); 
			return pHead;
		}
	}  
	free(pNew);//释放没有用到的空间; 
	return pHead;
  } 

上面我们提到了一个结构体的一个概念(我用红色表面了一下)

这里其实是因为一个学生,他的基本信息是有很多的:我们这里就有学号、姓名、性别、年龄、备注等。

这里年龄我们也要准确到年月日,所以我们就需要来一个结构体的嵌套了(这就是所谓的套娃吧,其实我们也可以不用的,也可以都放到一个结构体里面)

②.结构体代码如下:

#define  N  66//此处直接用宏定义定义学生人数
struct date//出生年月的结构体变量 
{
	int year;
	int month;
	int day;
}; 
struct Student
{
	long int num;//学号
	char name[20];//姓名
	char sex[3];//性别
	struct date birthday;
	int age; //年龄
	char bz[50];//备注 
	struct Student *pNext;//首先我们创造一个节点,表示每一个学生,
	//此处指向下一个节点的指针 
 }ss[N];

 ③.我们已经对学生的基本信息录入完成了,那么接下来就是输入学生的基本信息了,也就是显示出学生的基本信息

这里我们也是直接上代码:

void  Print(struct Student* pHead)//我们现在用链表输出数据; 
  {
  	struct Student *pTemp;//这是我们创建的临时在循环所需要的指针;
	int ilndex=1;//表示链表中节点的序号
	
	printf("*****the List has %d members:*****\n", iCount);//消息提示 
	printf("\n"); 
	//pTemp=pHead;//我们定义的指针得到首节点的地址
	
	for(pTemp=pHead;pTemp;pTemp=pTemp->pNext)
	{
		printf("the NO %d member is :\n", ilndex);
		printf("     学号:%5ld", pTemp->num);
		printf("     姓名:%5s", pTemp->name);
		printf("     性别:%5s", pTemp->sex);
		printf("     年:%5d", pTemp->birthday.year);
		printf("     月:%5d", pTemp->birthday.month);
		printf("     日:%5d", pTemp->birthday.day);
		printf("     年龄:%5d", pTemp->age=(2022-pTemp->birthday.year));
		printf("     备注:%5s", pTemp->bz);
		printf("\n");
		ilndex++;
	 } 
  }

 这里当时我也到一个问题,那就是,我们录入之后,我们显示的时候如果单单只用%d的话,可能会输出的时候是乱的,这里我就用了%5d来解决,其实就是让他变大了显示的位置(这样理解就好了)

④.学生基本信息的保存(这里我们就需要运用到文件了,文件可算是个比较难的鬼东西了)

也是老套路:直接上代码:

void save1(struct Student* pHead)//n就相当于我们学生的人数,与N相关联 
  {//保存基本信息函数; 
  	FILE *fp;
  	struct Student *ptr;//此处我们定义一个新的指针,去遍历输入内容保存文件里面 
  	if((fp=fopen("keshe.txt", "w+"))==NULL)//以只写的方式打开课设文件 
  	{
  		printf("file cannot open!");
  		exit(0);
	}
	for(ptr=pHead;ptr;ptr=ptr->pNext)
	{
		fprintf(fp,"     学号:%5ld", ptr->num);
		fprintf(fp,"     姓名:%5s", ptr->name);
		fprintf(fp,"     性别:%5s", ptr->sex);
		fprintf(fp,"     年:%5d 月:%5d 日:%5d", ptr->birthday.year,ptr->birthday.month,ptr->birthday.day);  
		fprintf(fp,"     年龄:%5d", ptr->age=(2022-ptr->birthday.year));
		fprintf(fp,"     备注:%5s", ptr->bz);
		fprintf(fp,"\n");
	}
	fclose(fp); 
  }
  

这里面呢,就是文件的一些基本的知识就可以解决我们的需求了,如果不是很懂文件,那就可以先去学习一下下,这里我也解释不太清楚,哈哈哈。

⑤.接下来,就是删除学生基本信息。

void Delete(struct Student *pHead, int ilndex)//ilndex表示要删除的学号; 
  {//学生基本信息删除函数 
  	struct Student* pTemp;
  	pTemp=pHead;
  	for(pTemp; ;pTemp=pTemp->pNext)
  	{
  	/*	if(pHead->num==ilndex)
  		{
  			pHead=pHead->pNext;
  			break;
		}*/
		if(pTemp->pNext->num==ilndex&&pTemp->pNext->pNext==NULL)
				{
					pTemp->pNext=NULL;
					break;
				}//这个判断是为了删除尾节点; 
  		if(pTemp->pNext->num==ilndex)
  		{
  			pTemp->pNext=pTemp->pNext->pNext;
  			break;
		}//这个是为了删除中间的信息; 
	}
  } 

这里,写的不算完美的,因为呀,我链表学的也不是很扎实,在创建链表的时候呢,好像头指针里面是有东西的,所以这里我们在删除学生基本信息的时候,我们是删除不了学号为1的学生的(也就是我们第一个录入的学生),其他的都是可以的。

⑥.查找学生基本信息

void search();//我们定义查询函数,这是总的查询函数,做个函数声明 
  void find1()//按学号查询; 
  {
  	int isprime=0;//此变量用来查询是否查找成功 
  	long int xhcx;
  	printf("请输入你要查询的学号:\n"); 
  	scanf("%ld", &xhcx);
  	struct Student *ptr1;
  	for(ptr1=pHead;ptr1;ptr1=ptr1->pNext)
  	{
  		if(xhcx==ptr1->num)
	    {
			printf("恭喜你,确有此人!\n");
			printf("学号:%ld,姓名:%s,年龄:%d,备注:%s\n", ptr1->num,ptr1->name,ptr1->age,ptr1->bz);		  	
			isprime=1;
			break;
		}	
	}
  		if(isprime==0)
  		{
  			printf("查询无果!\n");
		  }
  } 
  void find2()//按姓名查询; 
  {
  	int isprime1=0;
  	char xmcx[20];
  	printf("请输入你要查询的姓名:\n");
  	scanf("%s", &xmcx);
  	struct Student *ptr2;
  	for(ptr2=pHead;ptr2;ptr2=ptr2->pNext)
  	{
  		if(strcmp(xmcx,ptr2->name)==0)
	    {
			printf("恭喜你,确有此人!\n");
			printf("学号:%ld,姓名:%s,年龄:%d,备注:%s\n", ptr2->num,ptr2->name,ptr2->age,ptr2->bz);		  	
			isprime1=1;
			break;
		}	
	}
  		if(isprime1==0)
  		{
  			printf("查询无果!\n");
		  }
  }
  void find3()//按性别查询; 
  {
  	int isprime2=0;
  	char xbcx[3];
  	printf("请输入你要查询的性别:\n");
  	scanf("%s", &xbcx);
  	struct Student *ptr3;
  	for(ptr3=pHead;ptr3;ptr3=ptr3->pNext)
  	{
  		if(strcmp(xbcx,ptr3->sex)==0)//我们性别还没搞好; 
	    {
			printf("恭喜你,确有此人!\n");
			printf("学号:%ld,姓名:%s,年龄:%d,备注:%s\n", ptr3->num,ptr3->name,ptr3->age,ptr3->bz);		  	
			isprime2=1;
			
		}	
	}
  		if(isprime2==0)
  		{
  			printf("查询无果!\n");
		  }
  }
  void find4()//按年龄查询; 
  {
  	struct Student *ptr4;
  	int isprime3=0;
  	int nlcx;
  	printf("请输入你要查询的年龄:\n");
  	scanf("%d", &nlcx);
  	for(ptr4=pHead;ptr4;ptr4=ptr4->pNext)
  	{
  		if(nlcx==ptr4->age)
	    {
			printf("恭喜你,确有此人!\n");
			printf("学号:%ld,姓名:%s,年龄:%d,备注:%s\n", ptr4->num,ptr4->name,ptr4->age,ptr4->bz);		  	
			isprime3=1;
			
		}	
	}
  		if(isprime3==0)
  		{
  			printf("查询无果!\n");
		  }
  }
  void search()
  {//查询信息函数 
  	struct Student* pHead;
  	 printf("\t*****请输入你要查询的方式*****\n");
	 printf("\t***1.按学号查询***\n");
	 printf("\t***2.按姓名查询***\n");
	 printf("\t***3.按性别查询***\n");
	 printf("\t***4.按年龄查询***\n");
	 int m;
	
	 do
	 { 
	 scanf("%d", &m);
	 switch(m)
	  {
	 	case 1:find1();break;
		case 2:find2();break;
		case 3:find3();break;
		case 4:find4();break;
		default:
			printf("输入错误,请重新输入!\n");break;	
	  }
	 }while(m!=0);
  } 

查找学生的基本信息,你看我第二张图片的思维导图,你就会发现,查找我也分了好几个点来写。这样分成四个小部分,其实你会写其中一种,另外三种那还不是手到擒来?直接拿下好吧!

⑦.修改学生基本信息

void modify()
   {//修改信息函数 
   		int xgxx, isprime1=1; 
   		struct Student *xg;//我们定义一个修改的指针 
   		xg=pHead;//赋给它头指针; 
   		printf("\t***请输入你要修改哪项信息***\n");
   		printf("\t***1.修改学号***\n");
	    printf("\t***2.修改姓名***\n");
	    //printf("\t***3.修改性别***\n");
	    printf("\t***3.修改年龄***\n");
	 do
	 { 
	 scanf("%d", &xgxx);
	 switch(xgxx)
	  {
	 	case 1: long int xh1;
		 	    printf("\t***请输入你要修改的学号***\n");
				scanf("%ld", &xh1);
				for(xg; xg ;xg=xg->pNext)
				{
					if(xg->num==xh1)
					{
						printf("\t***请输入你修改后的学号***\n");
						long int xh2; 
						scanf("%ld", &xh2);
						xg->num=xh2;
						printf("\t***修改成功!***\n");
						break;
					}
				}
				isprime1=0;
				break;
		case 2: char xm1[20];
		 	    printf("\t***请输入你要修改的姓名***\n");
				scanf("%s", &xm1);
				for(xg; xg ;xg=xg->pNext)
				{
					if(strcmp(xg->name,xm1)==0)
					{
						printf("\t***请输入你修改后的姓名***\n");
						char xm2[20]; 
						scanf("%s", &xm2);
						strcpy(xg->name,xm2);
						printf("\t***修改成功!***\n");
						break;
					}
				}
				isprime1=0;
				break;
		//case 3:find3();break;
		case 3:int nl1;
		 	    printf("***\t请输入你要修改的年龄***\n");
				scanf("%d", &nl1);
				for(xg; xg ;xg=xg->pNext)
				{
					if(xg->age==nl1)
					{
						printf("\t***请输入你修改后的年龄***\n");
						long int nl2; 
						scanf("%ld", &nl2);
						xg->age=nl2;
						printf("\t***修改成功!***\n");
						break;
					}
				}
				isprime1=0;
				break;
		default:
			printf("输入错误,请重新输入!\n");break;	
	  }
	 }while(isprime1!=0);
   }

这里其实思路倒不是很难,我们要修改什么,我们就找出它来,然后用if语句去判断就好啦。

⑧.我们的这些基本的功能都实现了,那就是美化我们的代码了,那么今天我就教你们一个好方法,写菜单函数,哈哈哈。其实就是简单的输出语句(把格式搞得漂亮一些就好了)。

void menu()//菜单界面 
{ 
	printf("\t********欢迎进入登录班级档案管理系统********\n");
	printf("\t|***********1.学生基本信息录入*************|\n");
	printf("\t|***********2.学生基本信息显示*************|\n");
	printf("\t|***********3.学生基本信息保存*************|\n");
	printf("\t|***********4.学生基本信息删除*************|\n");
	printf("\t|***********5.学生基本信息修改*************|\n");
	printf("\t|***********6.学生基本信息查询*************|\n");
	printf("\t|***********    7.退出系统    *************|\n");
	printf("\t|*********请输入您要执行的功能(0~7)********|\n");
}

最后,我说了这么多,其实我感觉还是有些东西说的不是那么的明白,这里就是把一些实现功能的函数放到了这里,简单的复制拼接是行不通的。

这里还差主函数和一些头文件的代码,我还没有放到这里面。

具体的全部代码,我会单独写一个(里面包括演示界面,还有添加的功能(登录密码)等),并放到里面,大家可以去我主页查看就好啦!

 

  • 14
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值