⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hotel.c

📁 拿“优”的数据结构课程设计:模拟旅馆管理系统的床位的分配与回收功能。 里头包括源代码、exe文件、课程设计报告。非常全
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -