c语言数据结构项目——基于Hash表的疫情期间的人员管理系统

发布于:2023-01-10 ⋅ 阅读:(195) ⋅ 点赞:(0)

目录

前言:

项目说明:

功能目录:

 项目的代码实现:

头文件:

      1.定义hash表 

        2.创建hash表

        3.创建hash函数

        4.对信息的输入

        5.显示信息

        6.删除信息

        7.查找指定人员信息

        8.修改人员信息

        9.销毁hash表

主函数

1.保存到文件

2.菜单

3.信息的输入 ———switch选择

4.显示信息

5.改变患病状态

6.查找指定人员

7.修改人员信息

   mian函数整体代码:

子函数的封装

1.创建hash表

2.创建hash函数

3.输入信息

4.显示

5.删除信息

6.查找指定人员信息

7.修改人员信息

8.销毁hash表

运行结果

 写在末尾:


前言:

首先呢,这个项目也是对自己学习c语言和数据结构这么久成果的一个检验,也有很多想实现的功能没有实现,在以后的学习中会慢慢进行补全。

项目说明:

项目名称:基于c语言的疫情期间人员管理系统

项目背景:在疫情常态化的今天,面对时不时的疫情的传播与爆发,这其中的主要原因就是人员

                 的流动性,对此,开发此项目来进行对各区域的人流量及去向等信息作以整合和分析,

                 能够精确防控,帮助疫情时期的传播控制

项目功能:

                 1.能够收集和存储来往人员的相关信息,包括姓名,手机号码,身份证号,过往行程及

                   核酸检测结果,在确认有风险感染或已经感染后能够做到快速定位到个体,实现精

                   准防控

                  2.能够便捷修改和输入有关人员的疫情防控信息,加快了对高危人群及易感人群的

                    排查及更新的速度

                  3.能够将所有经过此地的人员的信息进行永久保存,可随时查看之前的信息并且有

                   助于疫情溯源,实现快速,精准防疫

功能目录:

 项目的代码实现:

        首先呢,要实现一个管理系统,首选要具备的是熟悉对于hash表的操作与理解,熟悉如何创建一个hash表以及hash函数并对其进行增删改查的操作;hash表的本质还是一个数组,我们对其操作只需要通过hash函数找到其对应的下标就可以找到其下标对应的链表的首地址,也就找到了我们所存放的数据,并可以对其进行操作。

头文件:

#ifndef _A_H
#define _A_H

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define SIZE 50

      1.定义hash表 

//定义数据元素的类型
typedef struct information
{
	int num;//编号
	char name[10]; //姓名
	char sex[10];  //性别
	char phone[12];  //电话号码  11位
	char  idcard[19];    //身份证  18位
	char status[20];   //感染状态
	char trip[30];   //行程(14天内去过的城市)
}data_type;

//定义链表节点的数据类型
typedef struct LinkNode
{
	data_type data;
	struct LinkNode *pNext;
}Link;

//定义hash表的数据类型
typedef struct hash
{
	Link *pArr[SIZE];
	int count; //统计的人员数量
	int lastNum; //最后一个人员的编号
}Hash;

        2.创建hash表

//创建一个hash表
//参数:void
//返回值:成功返回hash表的首地址,失败返回NULL
Hash *createHash(void);

        3.创建hash函数

//创建hash函数
//参数:key值
//返回值:下标
int hashFunc(int key);

        4.对信息的输入

//输入信息
//参数一:hash表结构体的首地址   Hash *pHash
//参数二:要素插入的数据  data_type item
//返回值:成功返回ok,失败返回原因
int inpute_Inf(Hash *pHash,data_type item);

        5.显示信息

//显示
//参数:hash表的首地址
//返回值:成功返回ok,失败返回原因
int show_Inf(Hash *pHash);

        6.删除信息

//删除信息
//参数一:hash表的首地址
//参数二:要删除的编号
//返回值:成功返回ok,失败返回原因
int delete_Inf(Hash *pHash,int num);

        7.查找指定人员信息

//查找指定人员信息
//参数一:hash表的首地址
//参数二:要查找的人员的编号
//参数三:保存要查找的数据
//返回值:成功返回ok,失败返回原因
int search_Inf(Hash *pHash, int num, data_type *pData);

        8.修改人员信息

//修改人员信息
//参数一:hash表的首地址
//参数二:要修改的人员的信息
//返回值:成功返回ok,失败返回原因
int change_Inf(Hash *pHash,data_type newData);

        9.销毁hash表

//销毁hash表
//参数:hash表首地址
//返回值:成功返回ok,失败返回原因
int destroy_Inf(Hash **pHead);


#endif

主函数

1.保存到文件

        将所有信息都保存到一个文件中,以便于后来的查看和查找

 这里时main函数开头时先行读取文件内容,若文件存有信息,则读取文件内容,将其导入,后续  可对其进行操作

    data_type InformationData;
	Hash *pHash = createHash();
	//打开文件
	int fr = open("Information.txt",O_RDONLY);
	if(fr < 0)
	{
		perror("open error");
		return -1;
	}
	//操作文件
	while(1)
	{
		int rd_count = read(fr,&InformationData,sizeof(data_type));
		if(0 == rd_count)
		{
			printf("导入信息完毕!\n");
			break;
		}
		else if(rd_count < 0)
		{
			printf("导入失败!\n");
			return ERROR;
		}
		else
		{
			inpute_Inf(pHash,InformationData);//将读到的信息插入到hash表中
			pHash->lastNum++;
		}
	}
	//关闭文件
	close(fr);

将输入后的信息保存在文件中,这里将保存操作写在main函数最后位置,即当用户操作完毕退出程序时程序会自动先进行保存操作,以免数据丢失

//将信息保存到文件中
	//打开文件
	int fw = open("Information.txt",O_WRONLY | O_CREAT,0664);
	if(fw < 0)
	{
		perror("open error");
		return -1;
	}
	//操作文件
	int i;
	for(i = 0; i < pHash->lastNum; i++)
	{
		Link *pHead = pHash->pArr[i];
		while(pHead != NULL)
		{
			//写入
			int fw_count = write(fw,&pHead->data,sizeof(data_type));
			if(0 == fw_count)
			{
				printf("倒入失败!\n");
				break;
			}
			else if(fw_count < 0)
			{
				printf("倒入失败!\n");
				break;
			}
			pHead = pHead->pNext;
		}
	}
	//关闭文件
	close(fw);
	printf("释放前:%p\n",pHash);
	destroy_Inf(&pHash);
	printf("释放后:%p\n",pHash);

2.菜单

while(1)
	{
		printf("----------------疫情管理系统----------------\n");
		printf("1-----------------------  inpute information(输入信息)\n");
		printf("2-----------------------  show information(显示信息)\n");
		printf("3-----------------------  delete information(改变人员患病状态)\n");
		printf("4-----------------------  search information(查找信息)\n");
		printf("5-----------------------  change information(修改信息)\n");
		printf("0-----------------------  exit(退出程序)\n");
		printf("--------------------------------------------\n");
		printf("请输入选项:\n");
		scanf("%d",&op);
		if(0 == op)
		{
			break;
		}

3.信息的输入 ———switch选择

switch(op)
		{
			case 1:
				item.num = pHash->lastNum + 1;
				pHash->lastNum++;
				printf("请输入人员的姓名:\n");
				scanf("%s",item.name);
				printf("请输入人员的性别:\n");
				scanf("%s",item.sex);
				printf("请输入人员的电话号码:\n");
				scanf("%s",item.phone);	
				if(strlen(item.phone) != 11 )
				{
					printf("电话号码输入有误!\n");
					continue;
				}
				printf("请输入人员的身份证:\n");
				scanf("%s",item.idcard);
				if(strlen(item.idcard) != 18 )
				{
					printf("身份证输入有误!\n");
					continue;
				}
				printf("请输入人员的感染状态:\n");
				scanf("%s",item.status);
				printf("请输入人员的行程:\n");
				getchar();
				gets(item.trip);
				inpute_Inf(pHash,item);
				break;

4.显示信息

case 2:        
                printf("信息显示如下:\n");
				show_Inf(pHash);
				break;
                

5.改变患病状态

case 3:
				printf("请输入要改变状态的人员的编号:\n");
				scanf("%d",&num);
				delete_Inf(pHash,num);
				break;

6.查找指定人员

case 4:
				printf("请输入要查找的编号:\n");
				scanf("%d",&num);
				search_Inf(pHash,num,NULL);
				break;

7.修改人员信息

case 5:
				{
					printf("请输入要修改的信息的人员的编号:\n");
					scanf("%d",&num);
					search_Inf(pHash,num,&item);
					while(1)
					{
						
						printf("1-----------修改电话号码\n");
						printf("2-----------修改身份证\n");
						printf("3-----------修改感染状态\n");
						printf("4-----------修改行程\n");
						printf("0-----------修改完毕\n");
						printf("请输入选项:\n");
						scanf("%d",&op1);
						if(0 == op1)
						{
							break;
						}
						switch(op1)
						{
									
							case 1:
								printf("请输入要修改的人员的电话号码:\n");
								scanf("%s",item.phone);
								break;
							case 2:
								printf("请输入要修改的人员的身份证:\n");
								scanf("%s",item.idcard);
								break;
							case 3:
								printf("请输入要修改的人员的感染状态:\n");
								scanf("%s",item.status);
								break;
							case 4:
								printf("请输入要修改的人员的行程:\n");
								getchar();
								gets(item.trip);
								break;
						}
						
					}
					change_Inf(pHash,item);
					break;
				}
			}    //这里的‘}’是最外围switch的右括号
	}     //这里的 ‘}’是上面wehile的右括号

mian函数整体代码:

#include"../include/a.h"
int main(int argc, const char *argv[])
{
	int op;
	int op1;
	int num;
	data_type item;
	data_type InformationData;
	Hash *pHash = createHash();
	//打开文件
	int fr = open("Information.txt",O_RDONLY);
	if(fr < 0)
	{
		perror("open error");
		return -1;
	}
	//操作文件
	while(1)
	{
		int rd_count = read(fr,&InformationData,sizeof(data_type));
		if(0 == rd_count)
		{
			printf("导入信息完毕!\n");
			break;
		}
		else if(rd_count < 0)
		{
			printf("导入失败!\n");
			return ERROR;
		}
		else
		{
			inpute_Inf(pHash,InformationData);//将读到的信息插入到hash表中
			pHash->lastNum++;
		}
	}
	//关闭文件
	close(fr);
	while(1)
	{
		printf("----------------疫情管理系统----------------\n");
		printf("1-----------------------  inpute information(输入信息)\n");
		printf("2-----------------------  show information(显示信息)\n");
		printf("3-----------------------  delete information(改变人员患病状态)\n");
		printf("4-----------------------  search information(查找信息)\n");
		printf("5-----------------------  change information(修改信息)\n");
		printf("0-----------------------  exit(退出程序)\n");
		printf("--------------------------------------------\n");
		printf("请输入选项:\n");
		scanf("%d",&op);
		if(0 == op)
		{
			break;
		}
		switch(op)
		{
			case 1:
				item.num = pHash->lastNum + 1;
				pHash->lastNum++;
				printf("请输入人员的姓名:\n");
				scanf("%s",item.name);
				printf("请输入人员的性别:\n");
				scanf("%s",item.sex);
				printf("请输入人员的电话号码:\n");
				scanf("%s",item.phone);	
				if(strlen(item.phone) != 11 )
				{
					printf("电话号码输入有误!\n");
					continue;
				}
				printf("请输入人员的身份证:\n");
				scanf("%s",item.idcard);
				if(strlen(item.idcard) != 18 )
				{
					printf("身份证输入有误!\n");
					continue;
				}
				printf("请输入人员的感染状态:\n");
				scanf("%s",item.status);
				printf("请输入人员的行程:\n");
				getchar();
				gets(item.trip);
				inpute_Inf(pHash,item);
				break;
				
			case 2:
				show_Inf(pHash);
				break;
			case 3:
				printf("请输入要改变状态的人员的编号:\n");
				scanf("%d",&num);
				delete_Inf(pHash,num);
				break;
			case 4:
				printf("请输入要查找的编号:\n");
				scanf("%d",&num);
				search_Inf(pHash,num,NULL);
				break;
			case 5:
				{
					printf("请输入要修改的信息的人员的编号:\n");
					scanf("%d",&num);
					search_Inf(pHash,num,&item);
					while(1)
					{
						
						printf("1-----------修改电话号码\n");
						printf("2-----------修改身份证\n");
						printf("3-----------修改感染状态\n");
						printf("4-----------修改行程\n");
						printf("0-----------修改完毕\n");
						printf("请输入选项:\n");
						scanf("%d",&op1);
						if(0 == op1)
						{
							break;
						}
						switch(op1)
						{
									
							case 1:
								printf("请输入要修改的人员的电话号码:\n");
								scanf("%s",item.phone);
								break;
							case 2:
								printf("请输入要修改的人员的身份证:\n");
								scanf("%s",item.idcard);
								break;
							case 3:
								printf("请输入要修改的人员的感染状态:\n");
								scanf("%s",item.status);
								break;
							case 4:
								printf("请输入要修改的人员的行程:\n");
								getchar();
								gets(item.trip);
								break;
						}
						
					}
					change_Inf(pHash,item);
					break;
				}
			}
	}
	//将信息保存到文件中
	//打开文件
	int fw = open("Information.txt",O_WRONLY | O_CREAT,0664);
	if(fw < 0)
	{
		perror("open error");
		return -1;
	}
	//操作文件
	int i;
	for(i = 0; i < pHash->lastNum; i++)
	{
		Link *pHead = pHash->pArr[i];
		while(pHead != NULL)
		{
			//写入
			int fw_count = write(fw,&pHead->data,sizeof(data_type));
			if(0 == fw_count)
			{
				printf("倒入失败!\n");
				break;
			}
			else if(fw_count < 0)
			{
				printf("倒入失败!\n");
				break;
			}
			pHead = pHead->pNext;
		}
	}
	//关闭文件
	close(fw);
	printf("释放前:%p\n",pHash);
	destroy_Inf(&pHash);
	printf("释放后:%p\n",pHash);

	return 0;
}

子函数的封装

1.创建hash表

#include"../include/a.h"

//创建一个hash表
//参数:viod
//返回值:成功返回首地址,失败返回NULL
Hash *createHash()
{
	Hash *pHash = (Hash *)malloc(sizeof(Hash));
	if(NULL == pHash)
	{
		perror("malloc error!");
		return NULL;
	}
	//初始化空间
	memset(pHash,0,sizeof(Hash));
	return pHash;
}

2.创建hash函数

#include"../include/a.h"

//创建hash函数
int hashFunc(int key)
{
	return key-1;
}

3.输入信息

#include"../include/a.h"

//输入信息
int inpute_Inf(Hash *pHash,data_type item)
{
	if(NULL == pHash)
	{
		return HASHNULL;
	}
	//创建一个新的节点
	Link *pNew = (Link *)malloc(sizeof(Link));
	if(NULL == pNew)
	{
		perror("malloc error!");
		return MALLOCERROR;
	}
	memset(pNew,0,sizeof(Link));
	//将数据赋值给新的节点
	pNew->data = item;
	
	//通过hash函数获得要存储的下标
	int pos = hashFunc(item.num);
	//保护好后面的节点
	pNew->pNext = pHash->pArr[pos];
	//插入新值
	pHash->pArr[pos] = pNew;
	//count++
	pHash->count++;
	return ok;
}

4.显示

#include"../include/a.h"

//显示
int show_Inf(Hash *pHash)
{
	if(NULL == pHash)
	{
		return HASHNULL;
	}
	//遍历输出
	int i;
	Link *pFind = NULL;
	for(i=0;i < pHash->lastNum; i++)
	{
		//定义结构体指针指向链表首地址
		pFind = pHash->pArr[i];
		while(pFind != NULL)
		//若为NULL则代表此链表为空,指针指向下一个链表的首地址重新开始while
		{
			printf("------------------------------\n");
			printf("编号:%d\n",pFind->data.num);
			printf("姓名:%s\n",pFind->data.name);
			printf("性别:%s\n",pFind->data.sex);
			printf("电话号码:%s\n",pFind->data.phone);
			printf("身份证:%s\n",pFind->data.idcard);
			printf("感染状态:%s\n",pFind->data.status);
			printf("行程:%s\n",pFind->data.trip);
			printf("------------------------------\n");
			pFind = pFind->pNext;
		}
	}
	printf("统计总人数为:%d\n",pHash->count);
	
	return ok;
}

5.删除信息

#include"../include/a.h"
//删除信息(转为阴性)
int delete_Inf(Hash *pHash,int num)
{
	if(NULL == pHash)
	{
		return HASHNULL;
	}
	//判断编号是否正确
	if(num < 0 || num > pHash->lastNum)
	{
		return POSERROR;
	}
	//通过hash函数获得要删除的数据的下标
	int pos = hashFunc(num);
	//定义一个指针,指向链表的首节点
	Link *pHead = pHash->pArr[pos];
	if(NULL == pHead)
	{
		return NOBODY;
	}
	int op2;
	while(pHead != NULL)
	{
		if(pHead->data.num == num)
		{
			printf("1-----------------转为阴性\n");
			printf("2-----------------转为阳性\n");
			printf("--------------------------\n");
			printf("请输入选项:\n");
			scanf("%d",&op2);
			if(0== op2)
			{
				break;
			}
			switch(op2)
			{
			case 1:
				//转为阴性
				pHash->count++;
				strcpy(pHead->data.status,"阴性");
				printf("已将该人员患病状态改为阴性!\n");
				break;
			case 2:
				//转为阳性
				pHash->count--;
				strcpy(pHead->data.status,"阳性");
				printf("已将该人员患病状态改为阳性!\n");
				break;
			}
		}
		pHead = pHead->pNext;
	}
	return ok;
}

6.查找指定人员信息

#include"../include/a.h"
//查找人员信息
int search_Inf(Hash *pHash,int num,data_type *pData)
{
	if(NULL == pHash)
	{
		return HASHNULL;
	}
	//判断num是否正确
	if(num < 0 || num > pHash->lastNum)
	{
		return POSERROR;
	}
	//通过hash函数获得要查找的下标
	int pos = hashFunc(num);
	//定义一个指针,初始化为链表首节点
	Link *pHead = NULL;
	pHead =	pHash->pArr[pos];
	if(NULL == pHead)
	{
		return NOBODY;
	}
	while(pHead != NULL)
	{
		if(num == pHead->data.num)
		{
			if(NULL == pData)
			{
				//显示人员信息
				printf("------------------------------\n");
				printf("编号:%d\n",pHead->data.num);
				printf("姓名:%s\n",pHead->data.name);
				printf("性别:%s\n",pHead->data.sex);
				printf("电话号码:%s\n",pHead->data.phone);
				printf("身份证:%s\n",pHead->data.idcard);
				printf("感染状态:%s\n",pHead->data.status);
				printf("行程:%s\n",pHead->data.trip);
				printf("------------------------------\n");
			}
			else
			{
				*pData = pHead->data;
			}
		}
		pHead = pHead->pNext;
	}
	return ok;
}

7.修改人员信息

#include"../include/a.h"
//修改人员信息
int change_Inf(Hash *pHash,data_type newData)
{
	if(NULL == pHash)
	{
		return HASHNULL;
	}
	//通过hash函数获得要修改的下标
	int pos = hashFunc(newData.num);
	//定义一个指针,初始化为链表首节点
	Link *pHead = NULL;
	pHead = pHash->pArr[pos];
	if(NULL == pHead)
	{
		return NOBODY;
	}
	while(pHead != NULL)
	{
		if(pHead->data.num == newData.num)
		{
			pHead->data = newData;
		}
		pHead = pHead->pNext;
	}
	return ok;
}

8.销毁hash表

#include"../include/a.h"
//销毁hash表
int destroy_Inf(Hash **pHead) //pHead = &pHash   *pHead = pHash
{
	//1.入参判断
	if(NULL == *pHead)
	{
		return HASHNULL;
	}
	int i;
	//定义一个指针,初始化为首节点
	Link *pFind = NULL;
	Link *pDel = NULL;
	for(i = 0; i < (*pHead)->lastNum; i++)
	{
		pFind = (*pHead)->pArr[i];
		while(pFind != NULL)
		{
			//头删法
			pDel = pFind;
			pFind = pFind->pNext;
			free(pDel);
			pDel = NULL;
		}
	}
	free(*pHead);
	*pHead = NULL;

	return ok;
}

运行结果

1.进来后输入选项2显示一下,文件为空

 

2. 然后从键盘输入1开始录入信息。注:输入手机号和身份证号码时输错程序会有判断

 输入成功:

 输入失败需要重新输入:

 

3.现在来显示一下内容看看

 

4.现在来改变人员的感染状态 

 先来看看个人的信息吧:

改变一下(柿子当然要变成阴性啦

 再来显示一下看改变状态下成功没有

 

 可以看到柿子的感染状态已经变阴性了!!!

5.查找人员

 

 两个都找到并且显示出来

6.修改信息——2号西西的行程都跑到火星了,得修改一下

 

 这就修改完毕,再次显示查看一下

 成功!!!

7.然后就可以按0退出程序,会自己保存数据的!!

 

 可以通过这个看到是否将空间释放成功

8.那就可以再次运行程序看看是否自己保存了数据还有是否能够自动读入

 

读取成功!!!

 写在末尾:

        这个系统暂时还不是很满意,其中还有很多功能没有实现,以后还得慢慢丰富其功能,暂时还有很多东西需要去学习和运用,其中代码或者功能中哪里有错误的地方,希望看见的大佬能够加已指正或者提出出建议,感激不尽!


网站公告

今日签到

点亮在社区的每一天
去签到

热门文章