宿舍管理系统——单链表+结构体实现入住、退房和查询功能(C语言版)

转自我的博客园(含全部源码):https://www.cnblogs.com/xiao-qi-w/p/13125080.html

编译和运行环境如下(如果有运行方面的问题欢迎在评论区留言,也欢迎直接加QQ:2961439733,备注博客园或CSDN即可):

  • 编辑工具:Dev-C++(版本:5.11.0.0)
  • 编译器:TDM-GCC 4.9.2 64-bit Release
  • 代码生成语言标准:ISO C99

演示及讲解视频链接:https://www.bilibili.com/video/BV1BC4y1a78W

好了开始进入正题,这次又双叒叕是我那位朋友的题目,不过已经是最后一题了。

课题四:信息管理系统

利用链表编写下列程序(二选一)

1、宿舍管理软件

用C语言为学生宿舍管理人员编写一个宿舍管理软件。设某宿舍有:101,102,201,202四个房间,每个房间可住学生<=4人,链表存储结构:学号、姓名、房间号、后续指针,按房间号有序,实现学生的入住、退房和查询,按给定学号、姓名、房号查询。

2、学生成绩信息管理

对学生的成绩信息进行管理,学生信息包括:学号、姓名、学期、每门课程的成绩、平均成绩、名次。实现:学生信息的录入;修改;删除和查询,按学期、学号、成绩不及格等查询。

要求:

  1. 要有菜单进行功能选择
  2. 各个功能要分到不同的函数来写
  3. 禁止使用goto语句
  4. 链表的各种操作要熟练掌握,会进行调试(调试我打算单独放一篇文章来讲,这篇主要讲怎么实现这个程序
  5. 链表结点如果使用malloc动态分配空间,需要释放

  看完题目我果断选择了第一题,不但好做,而且算是练手吧,因为第二题在我大一C语言课程设计时已经做过类似的了。那么来简单分析一下这个题如何下手:

首先先画出一个大致的流程图:

接下来就是实现功能1~n,我们确定一下要用到的数据结构。按要求采用链表实现,结点是记录住宿信息的结构体:

  struct DORMITORY {
    int num; //房间号
    char id[15]; //学号
    char name[20]; //姓名
    struct DORMITORY* next;//指针域
  };

  这里我还采用了设计数据库表时的一些思想,比如主键。用学号来标识唯一的一个结构体,避免出现一个人住多个寝室的情况。这里由于题目限制,最多只会有16名学生,所以采用大小确定的二维数组进行保存,用于核对学号是否已经存在。下面再来看看我们要实现的功能。

   功能不多,主要分为入住、退房和查询三大类。入住即添加一条新的住宿信息,也就是新建链表结点;退房意味着删除一条住宿信息,即从链表里删除一个节点;至于查找嘛,这几乎是所有的管理类程序都绕不开的一个功能,在这里表现为从链表中找到符合条件的节点。它们分别对应着三种对数据的基本操作——增、删、查。还有一种是修改,题目里没要求我也就没实现,各位看官如果有兴趣可以自行实现。接下来我们进入到代码的具体实现环节,其中字符串的比较与复制用到了库函数strcmp和strcpy。

  首先是主页面:采用一个死循环,不断接受输入来执行各种功能(其余展示页面同理)

void menu() { //主菜单
	char t;
	int flag = 1;
	while(flag) {
		system("cls"); //清屏, 然后输出新的内容
		printf("+--------------------+\n");
		printf("|    宿舍管理系统    |\n");
		printf("+--------------------+\n");
		printf("|  【1】入住 管理    |\n");
		printf("|                    |\n");
		printf("|  【2】退房 管理    |\n");
		printf("|                    |\n");
		printf("|  【3】信息 查询    |\n");
		printf("|                    |\n");
		printf("|  【4】使用 说明    |\n");
		printf("|                    |\n");
		printf("|  【5】退出 系统    |\n");
		printf("+--------------------+\n");
		t=getch();    //不回显输入
		switch(t) {
			case '1':
				checkIn();	 //入住管理
				break;
			case '2':
				checkOut();	 //退房管理
				break;
			case '3':
				menu_query();//信息查询
				break;
			case '4':
				direction(); //使用说明 
				break;
			case '5':
				printf("\n感谢您的使用,再见( ̄︶ ̄)↗");
				destroy();  //销毁链表,释放空间 
				flag = 0;	//结束程序
				break;
			default:
				break;
		}
	}
}

接下来我们依次实现主菜单里包含的功能:

  • 入住管理:
void checkIn() { //登记入住信息 
	char t;
	while(head->num > 0) {//还有空余房间,继续循环 
		system("cls"); 	  //清屏 
		dormitory node = create();//新建一个节点 
		if(node != NULL){ //创建成功 
			head->num -= 1;			 //剩余房间数减 1 
			node->next = head->next; //每次新结点的next指向头结点的next 
			head->next = node;	   	 //让头结点指向新建结点 
		}else{ //创建失败 
			printf("学号已存在,请重新进行添加操作!");
			break;
		}
		printf("\n+--------------------+");
		printf("\n|    是否继续添加    |");
		printf("\n+--------------------+");
		printf("\n|【1】是      【2】否|");
		printf("\n+--------------------+");
		t = getch();
		if(t == '1')
			continue;
		else
			break;
	}
	if(head->num == 0)//人数已满 
		printf("\n宿舍房间人数已满,无法继续入住!");
	printf("\n即将返回主菜单……"); 
	Sleep(1500); 	//暂停1.5秒后返回主菜单 
}

这里我们解释一下头插法的实现过程:

  1.首先建立一个头结点:

  2.然后新建结点p拷贝head的next指针:

  3.最后更改head的next的指针指向:

  

这种方式建立起来的链表是逆序的(相对于创建的先后顺序),不过不影响我们这个程序的功能实现。

  • 退房管理:
void checkOut() { //退房处理,按学号
	char id[15];
	int flag = 0; 
	dormitory p = head->next;
	system("cls"); //清屏 
	print(); 
	//按学号的好处是唯一,不会删除同一房间号或者重名学生的信息,数据库里学号相当于主键  
	printf("请输入要进行此操作的学生学号(如果是误触,请输入esc确认返回):\n");
	scanf("%s", id);
	if(!strcmp(id, "esc\0")){
		p =NULL;
		flag = 1; 
	} 
	for(; p != NULL; p = p->next){
		if(!strcmp(p->id, id)){
			del(p);	  //找到对应学号,删除
			head->num += 1;//剩余房间数加 1 
			printf("退房办理成功!"); 
			flag = 1;//把标志改为1 
		}
	} 
	if(!flag)
		printf("学号不存在!");
	printf("\n即将返回主菜单……"); 
	Sleep(1500); //暂停1.5秒后返回主菜单 
}
  • 信息查询(以按学号查询为例,其他的查询把代码里!strcmp(p->id, id)这个判断条件更改一下即可):
void findById() { //按学号查询 
	char t, id[15]; 
	int flag = 0; 
	dormitory p = head->next;
	system("cls"); //清屏 
	printf("请输入要查询的学生学号:\n");
	scanf("%s", id);
	printf("\n+-------------------------------+\n"); 
	printf("|         住宿信息(全)          |\n");
	printf("+-------------------------------+\n");
	printf("| 宿舍号 |   学   号   | 姓  名 |\n");
	printf("+-------------------------------+\n");
	for(; p != NULL; p = p->next){ //输出与目标学号一致的住宿信息
		if(!strcmp(p->id, id)){
			flag = 1;
			printf("|  %4d  | %11s | %6s |\n", p->num, p->id, p->name);
		}
	}
	printf("+-------------------------------+\n");
	if(!flag)
		printf("\n未找到相关信息(>﹏<)");
	while((t = getch()) != 27);//只有按下ESC键才会中断循环并返回 
}

核心流程里的代码就这些,其余的部分请参考源码(见文章开头博客园链接),希望你能在理解本程序的基础上完成文章开头提到的学生成绩信息管理,如果能在此基础上利用文件保存数据,相信你的水平能更上一层楼!

码文不易,看到这里如果对你有帮助的话不妨点个赞支持一波再走吧,3Q~ 😀

  • 6
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值