分享一下自己再学习中的一个实战小项目,利用hash表制作的一个信息管理系统,因为是使用Makefile写的所以整个程序分成了三部分,分别为:头文件部分、主函数部分、子函数部分。相关功能下方菜单中可见。
1.头文件部分
#ifndef _STORE_H
#define _STORE_H
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#define SIZE 100
//定义数据元素的类型
typedef struct store
{
//药品名称
char name[20];
//编号
int id;
//价格
float price;
//在售情况
char status[20];
//库存容量
int storage;
//存放位置
int pos;
}data_type;
//定义链表结点的数据类型
typedef struct LinkNode
{
data_type data;
struct LinkNode *pNext;
}Link;
//定义hash表的数据类型
typedef struct hash
{
Link *pArr[SIZE];
int count;//统计药品的种类数量
}Hash;
//定义枚举
enum res
{
LINKNULL=-7,
MASSAGENULL,
POSERROR,
HASHERROR,
HASHNULL,
CREATERROR,
MALLOCERROR,
OK
};
//菜单函数
void menu();
//创建hash表
//参数:void
//返回值:成功返回hash表的首地址,失败NULL
Hash *CreatHash();
//hash函数
//参数:key值
//返回值:成功返回存储下标
int HashFun(int key);
//插入数据
//参数1:hash表的首地址
//参数2:要插入的数据
//返回值:成功返回OK,失败返回失败原因
int InsertHash(Hash *pHash,data_type item);
//显示hash表内容
//参数:hash表的首地址
//返回值:成功返回OK,失败返回失败原因
int ShowHash(Hash *pHash);
//删除指定数据
//参数1:hash表的首地址
//参数2:药品编号
//返回值:成功返回OK,失败返回失败原因
int DeleteHash(Hash *pHash,int id);
//修改指定数据
//参数1:hash表的首地址
//参数2:药品编号
//参数3:修改的数据
//返回值:成功返回OK,失败返回失败原因
int ReviseHash(Hash *pHash,char *ch,data_type item);
//销毁hash表
//参数:hash表的首地址
//返回值:成功返回OK,失败返回失败原因
int DestroyHash(Hash **pHash);
//统计药品
//参数:hash表的首地址
//返回值:成功返回OK,失败返回失败原因
int CountHash(Hash *pHash);
//查询指定药品信息
//参数1:hash表的首地址
//参数2:药品编号
//返回值:成功返回OK,失败返回失败原因
int SearchHash(Hash *pHash,char *ch);
#endif
2.主函数部分
#include"../include/store.h"
int main()
{
int op,id;
char ch[20];
data_type item;
Hash *pHash = NULL;
pHash = CreatHash();
data_type messagedata;
//读取数据
//打开文件
int fr = open("message.txt",O_RDONLY | O_CREAT,0666);
if(fr < 0)
{
perror("open error");
return -1;
}
//操作文件
while(1)
{
int rd = read(fr,&messagedata,sizeof(data_type));
if(rd == 0)
{
break;
}
else if(rd < 0)
{
printf("导入信息失败!\n");
return -1;
}
else
{
//将文件读取到hash表中
InsertHash(pHash,messagedata);
pHash->count++;
}
}
//关闭文件
close(fr);
while(1)
{
menu();
printf("\033[;31;5m 请输入选项:\033[0m\n");
scanf("%d",&op);
if(0 == op)
{
printf("退出成功!\n");
break;
}
switch(op)
{
case 1:
printf("请输入药品名称:\n");
scanf("%s",item.name);
item.id = pHash->count+1;
printf("请输入药品价格:\n");
scanf("%f",&item.price);
printf("请输入药品在售情况:\n");
scanf("%s",item.status);
printf("请输入药品库存量:\n");
scanf("%d",&item.storage);
printf("请输入药品存放位置:\n");
scanf("%d",&item.pos);
InsertHash(pHash,item);
break;
case 2:
ShowHash(pHash);
break;
case 3:
printf("请输入需要删除的药品编号:\n");
scanf("%d",&id);
DeleteHash(pHash,id);
break;
case 4:
printf("请输入需要修改的药品名称:\n");
scanf("%s",ch);
//修改信息输入
printf("请输入要修改的药品名称:\n");
scanf("%s",item.name);
printf("请输要修改的药品编号:\n");
scanf("%d",&item.id);
printf("请输入要修改的药品价格:\n");
scanf("%f",&item.price);
printf("请输入要修改的药品在售情况:\n");
scanf("%s",item.status);
printf("请输入要修改的药品库存量:\n");
scanf("%d",&item.storage);
printf("请输入要修改的药品存放位置:\n");
scanf("%d",&item.pos);
ReviseHash(pHash,ch,item);
break;
case 5:
printf("请输入需要查询药品的编号\n");
scanf("%s",ch);
SearchHash(pHash,ch);
break;
}
}
// 将数据保存到文件
//打开文件
int fw = open("message.txt",O_WRONLY | O_CREAT,0666);
if(fw < 0)
{
perror("oopen error");
return -1;
}
//操作文件
int i;
for(i = 0;i <= pHash->count;i++)
{
Link *pFind = pHash->pArr[i];
while(NULL != pFind)
{
int wd = write(fw,&pFind->data,sizeof(data_type));
if(0 == wd)
{
printf("读取数据失败!\n");
break;
}
else if(0 > wd)
{
printf("读取数据失败!\n");
break;
}
pFind = pFind->pNext;
}
}
//关闭文件
close(fw);
//销毁Hash表
DestroyHash(&pHash);
return 0;
}
3.子函数部分
#include"../include/store.h"
//-----------------------菜单--------------------------------------
void menu()
{
printf(" ______________________________________________________\n");
//printf("|**********欢迎进入医用药物仓库存储管理系统************|\n");
printf("|\033[44;33;5m **********欢迎进入医用药物仓库存储管理系统***********\033[0m|\n");
printf("|1----------------------------------------插入药品信息!|\n");
printf("|2----------------------------------------显示库存信息!|\n");
printf("|3----------------------------------------删除药品信息!|\n");
printf("|4----------------------------------------修改药品信息!|\n");
printf("|5----------------------------------------查询药品信息!|\n");
printf("|0----------------------------------------退出程序! |\n");
printf("|******************************************************|\n");
printf("|______________________________________________________|\n");
}
//-----------------------hash函数----------------------------------
int HashFun(int key)
{
return key-1;
}
//-----------------------创建hash表--------------------------------
Hash *CreatHash()
{
Hash *pHash = (Hash *)malloc(sizeof(Hash));
if(NULL == pHash)
{
perror("malloc error");
return NULL;
}
memset(pHash,0,sizeof(Hash));
return pHash;
}
//-----------------------插入数据----------------------------------
int InsertHash(Hash *pHash,data_type item)
{
//入参判断
if(NULL == pHash)
{
return HASHNULL;
}
//创建一个新结点
Link *pNew = NULL;
pNew = (Link *)malloc(sizeof(Link));
if(NULL == pNew)
{
return MALLOCERROR;
}
memset(pNew,0,sizeof(Link));
pNew->data = item;
//通过hash函数查找存储位置
int pos = HashFun(item.id);
//保护插入后面的结点
pNew->pNext = pHash->pArr[pos];
//插入新值
pHash->pArr[pos] = pNew;
//count自加统计数量
pHash->count++;
}
//------------------------显示hash表内容---------------------------
int ConutHash(Hash *pHash);
int ShowHash(Hash *pHash)
{
//入参判断
if(NULL == pHash)
{
return HASHNULL;
}
//遍历hash表
int i;
Link *pFind = NULL;
printf(" _________________________________________________\n");
printf("|\033[44;37;1m 显示的药品信息为:\033[0m \n");
printf("|_________________________________________________\n");
ConutHash(pHash);
for(i = 0;i <= pHash->count;i++)
{
pFind = pHash->pArr[i];
while(NULL != pFind)
{
printf("|名称:%s\n",pFind->data.name);
printf("|编号:%d号\n",pFind->data.id);
printf("|价格:%.2f元\n",pFind->data.price);
printf("|在售情况:%s\n",pFind->data.status);
printf("|库存容量:%d件\n",pFind->data.storage);
printf("|存放位置:%d号货柜\n",pFind->data.pos);
printf("|_________________________________________________\n");
pFind = pFind->pNext;
}
}
return OK;
}
//-----------------------删除数据----------------------------------
int DeleteHash(Hash *pHash,int id)
{
//入参判断
if(NULL == pHash)
{
return HASHNULL;
}
//判断id是否正确
if(id < 0 || id > pHash->count)
{
return POSERROR;
}
//获取删除数据的位置
int pos = HashFun(id);
//定义一个指针初始化为首结点
Link *pFind = pHash->pArr[pos];
if(NULL == pFind)
{
return MASSAGENULL;
}
while(pFind != NULL)
{
if(pFind->data.id == id)
{
//下架
strcpy(pFind->data.status,"已下架");
}
pFind = pFind->pNext;
}
return OK;
}
//-----------------------销毁hash表----------------------------------
int DestroyHash(Hash **pHash)
{
//入参判断
if(NULL == (*pHash))
{
return HASHNULL;
}
//销毁结点
int i;
Link *pFind = NULL;
Link *pDel = NULL;
for(i = 0;i <=(*pHash)->count;i++)
{
pFind = (*pHash)->pArr[i];
while(NULL != pFind)
{
pDel = pFind;
pFind = pFind->pNext;
//释放结点
free(pDel);
pDel = NULL;
}
}
//释放hash表
free(*pHash);
*pHash = NULL;
return OK;
}
//------------------------数量统计---------------------------
int ConutHash(Hash *pHash)
{
//入参判断
if(NULL == pHash)
{
return HASHNULL;
}
//遍历hash表
int i;
int count1 = 0;
int count2 = 0;
int count3 = 0;
int count4 = 0;
char ch1[20] = "在售";
char ch2[20] = "已下架";
Link *pFind = NULL;
for(i = 0;i <= pHash->count;i++)
{
pFind = pHash->pArr[i];
while(NULL != pFind)
{
if(strcmp(ch1,pFind->data.status) == 0)
{
count1++;
}
if(strcmp(ch2,pFind->data.status) == 0)
{
count2++;
}
count3++;
count4 = count4 + pFind->data.storage;
pFind = pFind->pNext;
}
}
printf("|药品总数%d种\n",count3);
printf("|在售的药品%d件\n",count1);
printf("|下架的药品%d件\n",count2);
printf("|总库存量:%d件\n",count4);
printf("|_________________________________________________\n");
return OK;
}
//-----------------------指定查询----------------------------------
int SearchHash(Hash *pHash,char *ch)
{
//入参判断
if(NULL == pHash)
{
return HASHNULL;
}
int i;
Link *pFind = NULL;
for(i = 0;i <=pHash->count;i++)
{
pFind = pHash->pArr[i];
while(NULL != pFind)
{
if(strcmp(ch,pFind->data.name) == 0 )
{
printf("查询结果如下:\n");
printf(" _________________________________________________\n");
printf("|名称:%s\n",pFind->data.name);
printf("|编号:%d号\n",pFind->data.id);
printf("|价格:%.2f元\n",pFind->data.price);
printf("|在售情况:%s\n",pFind->data.status);
printf("|库存容量:%d件\n",pFind->data.storage);
printf("|存放位置:%d号货柜\n",pFind->data.pos);
printf("|_________________________________________________\n");
}
pFind = pFind->pNext;
}
}
return OK;
}
//-----------------------指定修改----------------------------------
int ReviseHash(Hash *pHash,char *ch,data_type item)
{
//入参判断
if(NULL == pHash)
{
return HASHNULL;
}
int i;
Link *pFind = NULL;
for(i = 0;i <=pHash->count;i++)
{
pFind = pHash->pArr[i];
while(NULL != pFind)
{
if(strcmp(ch,pFind->data.name) == 0 )
{
pFind->data = item;
}
pFind = pFind->pNext;
}
}
return OK;
}