📄 hotel.c
字号:
#include<stdio.h>
#include<stdlib.h>
//#include<conio.h>
#include<malloc.h>
#include"Status.h"
#include"Date.h"
#define MAX_BED 10
#define MAX_ROOM 10
//顾客信息类型
typedef struct guest
{
char name[20]; //姓名
int sex; //性别,0男,1女
int age; //年龄
date arrive; //到达时间
date leave; //离开时间
}guest, *guestptr;
//房间信息类型
typedef struct room
{
int Rnum; //房间号码
int Ebed[MAX_BED]; //本房间的空床栈,存储空床的编号
int Btop; //本房间空床栈栈顶
guestptr guest[MAX_BED+1]; //指向住在该房间旅客信息的节点,
//每一个指针指向一个床位,
//若床位空则指针为空
struct room *Rlink; //当房间空时当作空房栈的连接;
//当房间不空时,指向下一个房结点。
}room, *roomptr;
//各级别信息
typedef struct rank
{
int TRnum; //该级别房间总数
int RBnum; //该级别每房间床位数
int price; //该级别房间单位价格
int Ebed[2]; //0为该级别可分配的男床总数,1为该机可分配的女床总数
int Eroom[MAX_ROOM]; //空房间栈
int Rtop; //空房间栈栈顶指针
room* EBlink[2]; //0指向本级尚未住满的男客房栈栈顶,
//1指向本级尚未住满的女客房栈栈顶
room* FRlink[2]; //0指向本级已住满的男客房链
//1指向本级已住满的男客房链
}rank;
//旅馆所有信息
typedef struct hotel
{
rank rank[5]; //客房信息
date today; //当前日期
guestptr guest; //临时存储顾客信息
}hotel;
//函数声明
Status Init(hotel **H);//初始化旅店信息
Status GuestArrive(hotel *H);//顾客到达事件
Status AskGuestInfo(hotel *H, int *R);//询问顾客信息
Status DistributeBed(hotel* H, int R, int* RN, int* BN);//分配床位
Status PrintDistribute(hotel *H, int R, int RN, int BN);//打印房间分配表
Status GuestLeave(hotel *H);//顾客离开事件
Status AskGuestRoomBed(hotel *H, int *R, int *S, int *RN, int *BN);//询问顾客的性别、房间号和床位号
Status ReclaimBed(hotel *H, int R, int S, int RN, int BN);//回收床位
Status PrintAccount(hotel *H, int R, int S, int RN, int BN);//打印账单
Status PrintEmptyBed(hotel *H);//显示当前剩余客房
Status PrintMenu(hotel *H);//显示菜单
Status Chose(hotel *H, int C);//选择操作
//初始化旅店信息
Status Init(hotel **H)
{
//根据从文件读取到的信息进行初始化。
//读取房间等级数量,各等级房间数量、床位数、价格;
//根据读取到的信息进行初始化,包括分配存储空间并赋值。
FILE *fpData, *fpToday;
int i, j, k;
int rankNum;
//初始化局部变量
i = j = k = 0;
rankNum = 0;
if((fpData=fopen("data.dat","r"))==NULL) return FALSE;
//分配存储空间
(*H) = (hotel *)malloc(sizeof(hotel));
if (!(*H)) return FALSE;
//读取等级数量
fscanf(fpData, "%d,", &rankNum);
//读取各等级信息并对信息进行初始化
(*H)->rank[0].Ebed[0] = 0;
for (i=1; i<=rankNum; i++)
{
fscanf(fpData, "%d,", &(*H)->rank[i].TRnum); //该级别房间数
fscanf(fpData, "%d,", &(*H)->rank[i].RBnum); //该级别床位数
fscanf(fpData, "%d,", &(*H)->rank[i].price); //该级别单价
(*H)->rank[i].Ebed[0] = (*H)->rank[i].Ebed[1]
= (*H)->rank[i].TRnum * (*H)->rank[i].RBnum; //初始男女空房间数
(*H)->rank[0].Ebed[0] += (*H)->rank[i].Ebed[0]; //将该级别房间数计入总房间数
(*H)->rank[i].EBlink[0] = NULL;
(*H)->rank[i].EBlink[1] = NULL;
(*H)->rank[i].FRlink[0] = NULL;
(*H)->rank[i].FRlink[1] = NULL;
//初始化该级别房间信息
for (j=0; j<(*H)->rank[i].TRnum; j++)
{
(*H)->rank[i].Eroom[j] = i*100+j+1; //空房间号入栈
}
(*H)->rank[i].Rtop = j; //空房间栈栈顶
(*H)->guest = NULL;
}
(*H)->rank[0].Ebed[1] = (*H)->rank[0].Ebed[0];
(*H)->rank[0].TRnum = rankNum; //rnak[0].TRnum记录房间级别数量
//对rank[0]无用的结点赋初值
(*H)->rank[0].RBnum = 0;
(*H)->rank[0].price = 0;
(*H)->rank[0].EBlink[0] = NULL;
(*H)->rank[0].EBlink[1] = NULL;
(*H)->rank[0].FRlink[0] = NULL;
(*H)->rank[0].FRlink[1] = NULL;
fclose(fpData); //关闭data.dat文件
system("date /t > today.dat"); //将当前系统日期写入到today.dat文件中
//打开today.dat文件并从中读取当前日期
if((fpToday=fopen("today.dat","r"))==NULL) return FALSE;
fscanf(fpToday, "%d-", &(*H)->today.year);
fscanf(fpToday, "%d-", &(*H)->today.month);
fscanf(fpToday, "%d ", &(*H)->today.day);
fclose(fpToday); //关闭today.dat文件
return OK;
}//初始化旅店信息
//顾客到达事件
Status GuestArrive(hotel *H)
{
int rank;
int roomNum, bedNum;
char chose;
//函数局部变量赋初值
rank = roomNum = bedNum = 0;
chose = 'y';
//询问顾客信息(姓名、性别、年龄),需求的房间等级
AskGuestInfo(H, &rank);
//分配房间
if (H->rank[0].EBlink[H->guest->sex])
{
printf("\n\n 旅馆客满。");
printf("\n ");
system("pause");
system("cls");
return OK;
}//if //旅店已经客满
while (chose=='y' || chose=='Y')
{
if(!DistributeBed(H, rank, &roomNum, &bedNum))
{
printf(" 该级别房间已满,是否选择其他级别房间?");
scanf("%c", &chose);
scanf("%c", &chose);
if (chose=='y' || chose=='Y')
{
printf(" 请输入新的房间等级:");
scanf("%d", &rank);
}//if //选择重新选择房间等级
else if(chose=='n' || chose=='N')
{
free(H->guest);
H->guest = NULL;
}//if //选择不重新分配则删除旅客信息
else
{
chose = 'y';
}//else //输入了y和n以外的字母
}//if //分配不成功,询问是否重新输入
else
{
chose = 'n';
}//else //分配成功
}//while
//分配成功则打印房间分配表
if (roomNum)
{
PrintDistribute(H, rank, roomNum, bedNum);
}//if
return OK;
}
//询问顾客信息
Status AskGuestInfo(hotel *H, int *R)
{
guestptr tempGuest;
tempGuest = (guest *)malloc(sizeof(guest));
if (!tempGuest) return FALSE;
//记录顾客信息到临时结点
printf("\n\n 现在开始输入顾客需求信息\n");
printf(" 顾客姓名:");
scanf("%s", tempGuest->name); //姓名
printf(" 顾客性别:");
scanf("%d", &tempGuest->sex); //性别
while(tempGuest->sex<0 || tempGuest->sex>1)
{
printf(" 性别超出范围,请重新输入:");
scanf("%d", &tempGuest->sex);
}//while
printf(" 顾客年龄:");
scanf("%d", &tempGuest->age); //年龄
while(tempGuest->age<16 || tempGuest->age>99)
{
printf(" 年龄超出范围,请重新输入:");
scanf("%d", &tempGuest->age);
}//while
printf(" 需要的房间等级:");
scanf("%d", R);
while(*R<0 || *R>H->rank[0].TRnum)
{
printf(" 房间等级超出范围,请重新输入:");
scanf("%d", R);
}//while //房间等级
//旅客到达时间为当前程序日期
tempGuest->arrive.year = H->today.year;
tempGuest->arrive.month = H->today.month;
tempGuest->arrive.day = H->today.day;
H->guest = tempGuest; //将旅客信息结点返回
return OK;
}//询问顾客信息
//分配床位
Status DistributeBed(hotel* H, int R, int* RN, int* BN)
{
int i;
roomptr tempRoom;
int sex;
sex = H->guest->sex;
//查找该级别房间是否有空床位;
if (H->rank[R].Ebed[sex] > 0)
{
//查找该级别是否有没住满的房间
if (H->rank[R].EBlink[sex])
{
tempRoom = H->rank[R].EBlink[sex];
*RN = tempRoom->Rnum; //返回房间号码
tempRoom->Btop--; //栈顶指针下移
*BN = tempRoom->Ebed[tempRoom->Btop]; //空床位出栈,返回床位号
tempRoom->guest[*BN] = H->guest; //将顾客信息插入到该房间
H->rank[R].Ebed[sex]--; //该级别该性别可用空床数减一
H->rank[0].Ebed[sex]--; //该性别所有可用空床数减一
if(!tempRoom->Btop) //该房间客满客满
{
H->rank[R].EBlink[sex] = tempRoom->Rlink;
tempRoom->Rlink = H->rank[R].FRlink[sex];
H->rank[R].FRlink[sex] = tempRoom;
}//if 将该房间从空床栈移动到满床链
}//if 有,入住没住满的房间
else
{
//在内存中分配新房间空间,并对新房间进行初始化
tempRoom = (room *)malloc(sizeof(room)); //在内存中分配新房间
if (!tempRoom) return FALSE;
H->rank[R].Rtop--; //栈顶指针下移
tempRoom->Rnum = H->rank[R].Eroom[H->rank[R].Rtop]; //空房间出栈,赋值房间号码
for (i=0; i<H->rank[R].RBnum; i++)
{
tempRoom->Ebed[i] = i+1; //将空床加入到空床栈
tempRoom->guest[i+1] = NULL; //将空床加入到空床栈
}
tempRoom->Btop = i; //空床栈栈顶指针
//旅客入住
*RN = tempRoom->Rnum; //返回房间号码
tempRoom->Btop--; //栈顶指针下移
*BN = tempRoom->Ebed[tempRoom->Btop]; //空床位出栈,返回床位号
tempRoom->guest[*BN] = H->guest; //将顾客信息插入到该房间
H->rank[R].Ebed[sex]--; //该级别该性别可用空床数减一
H->rank[0].Ebed[sex]--; //该性别所有可用空床数减一
H->rank[R].Ebed[(sex-1)*(0-1)] -= H->rank[R].RBnum;
//该级别另一性别可用空床数减该级别每房间床数
H->rank[0].Ebed[(sex-1)*(0-1)] -= H->rank[R].RBnum;
//另一性别所有可用空床数减该级别每房间床数
if(!tempRoom->Btop) //该房间客满客满
{
tempRoom->Rlink = H->rank[R].FRlink[sex];
H->rank[R].FRlink[sex] = tempRoom;
}//if 将该房间从空房栈移动到满床链
else
{
tempRoom->Rlink = H->rank[R].EBlink[sex];
H->rank[R].EBlink[sex] = tempRoom;
}//else 将该房间从空房栈移到空床栈
}//else 没有,入住新房间
return OK;
}//if 有空床位,入住
else
{
return FALSE;
}//else
}//分配床位
//打印房间分配表
Status PrintDistribute(hotel *H, int R, int RN, int BN)
{
//姓名,年龄,到达日期,房间等级,房间号码,床位号码
char sex[2][3]={"男","女"};
printf("\n");
printf(" ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
printf(" ┃ 房 间 分 配 表 ┃\n");
printf(" ┣━━━━┯━━┯━━┯━━━━━━┯━━━━┯━━━━┯━━━━┫\n");
printf(" ┃ 姓名 │性别│年龄│到 达 日 期 │房间等级│房间号码│床位号码┃\n");
printf(" ┠────┼──┼──┼──────┼────┼────┼────┨\n");
printf(" ┃%6s │ %2s │ %2d │%5d-%2d-%2d │ %d │ %3d │ %d ┃\n",
H->guest->name,sex[H->guest->sex],H->guest->age,H->today.year,
H->today.month,H->today.day,R,RN,BN);
printf(" ┗━━━━┷━━┷━━┷━━━━━━┷━━━━┷━━━━┷━━━━┛\n");
printf("\n ");
system("pause");
system("cls");
return OK;
}//打印房间分配表
//顾客离开事件
Status GuestLeave(hotel *H)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -