/**********************************************************************************************************
停车场项目需求
问题描述:停车场是一个能放 n 辆车的狭长通道,只有一个大门,汽车按到达的先后次序停放。若车场满了,车要停在门
          外的便道上等候,一旦有车走,则便道上第一辆车进入。当停车场中的车离开时,由于通道窄,在它后面的车
    要先退出,待它走后在依次进入。汽车离开时按停放时间收费。
基本功能要求:(1)建立三个数据结构分别是:停放栈、让路栈、等候队列。
             (2)输入数据模拟管理过程,数据(入或出,车号)

功能描述:进车登记、出车登记、按车牌号查询停车车辆信息、查询出入车记录、
          查询场内车辆信息、查询等候车辆信息、退出系统。
          (1)linux系统编写(链表、栈、队列);
          (2)进车登记:登记车牌号以及入场时间;
          (3)出车登记:计算出停车时间,记录车辆车牌;
          (4)按车牌号查询车辆信息:停车时间,是否来过停车场,是否还在停车场
          (5)查询出入记录:所有车辆,包括已经离开的
          (6)查询场内车辆信息:列出所有场内车辆信息
    (7)查询等候车辆信息:显示等候车辆数量以及所有车牌号
          (8)退出系统。
**********************************************************************************************************/

1、定义数据结构体管理数据。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX 5     //车库容量
#define PRICE 5.0 //停车收费单价
#define Status int
typedef struct //车辆信息
{
    char number[10];   //车牌号
    int position;      //停车位置
    struct tm intime;  //进入时间  struct tm能获取当前时间
    struct tm outtime; //离开时间
    int time;          //停车时间
    int cost;          //停车费用
} CAR;
typedef struct
{
    CAR data[MAX];
    int top;
} Stack; //停放栈
typedef struct carnode
{
    CAR data;
    struct carnode *next;
} Carnode; //等候车辆结点

typedef struct carnode *LQueuePtr; //指向结点类型的指针
typedef struct lqueue
{
    LQueuePtr front;
    LQueuePtr rear;
} LQueue; //队列(链式)

2、实现各个函数功能。

Status InitStack(Stack *S) //初始化栈
{
    S->top = -1; //栈顶指针top指向-1
    return 0;
}

Status StackEmpty(Stack S) //判断栈空否
{
    if (-1 == S.top)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
Status StackFull(Stack S) //判断栈满否
{
    if (MAX - 1 == S.top)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
Status PushStack(Stack *S, CAR car) //入栈
{
    if (0 == StackFull(*S))
    {
        S->top++;
        S->data[S->top] = car;
    }
    return 0;
}
CAR PopStack(Stack *S) //出栈
{
    CAR car;
    if (0 == StackEmpty(*S))
    {
        car = S->data[S->top];
        S->top--;
    }
    return car;
}
Status InitLQueue(LQueue *Q) //初始化过道等候队列
{
    LQueuePtr p;
    p = (LQueuePtr)malloc(sizeof(Carnode)); //给链式队列分配一个头结点
    if (NULL == p)
    {
        printf("内存分配失败!\n");
        exit(0);
    }

    Q->front = p; //初始化队列的头、尾指针都指向头结点
    Q->rear = p;
    p->next = NULL;
    return 0;
}
Status LQueueEmpty(LQueue Q) //判断队列空否
{
    if (Q.front == Q.rear) //队列的头、尾指针相等则队列为空
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
Status PushLQueue(LQueue *Q, CAR car) //入队列  尾进
{
    LQueuePtr p;
    p = (LQueuePtr)malloc(sizeof(Carnode)); //分配一个进入队列的车辆结点
    if (NULL == p)
    {
        printf("内存分配失败!\n");
        exit(0);
    }

    p->data = car;
    p->next = NULL;
    Q->rear->next = p; //新的车辆结点成为原队尾的后继
    Q->rear = p;       //队尾指针指向新的队尾
    return 0;
}
CAR PopLQueue(LQueue *Q) //出队列  头出
{
    LQueuePtr p, q;
    CAR car;
    if (Q->front != Q->rear) //队列不为空
    {
        p = Q->front; //p指向头结点
        q = p->next;  //q指向第一个数据结点
        car = q->data;
        p->next = q->next; //头结点连上后面的结点
        if (q == Q->rear)  //若只有一个数据结点,出队列后队列为空,队列头、尾指针要一致
        {
            Q->rear = Q->front;
        }
        free(q); //释放第一个数据结点
    }
    return car;
}
Status LQueueLength(LQueue Q) //计算队列的长度,指针的移动来计数
{
    LQueuePtr p;
    int i = 0;
    p = Q.front->next;
    while (NULL != p)
    {
        p = p->next;
        i++;
    }
    return i;
}
Status PrintDate(struct tm gm) //输出当前时间  月份区间[0,11]
{
    printf("%d/%d %2d:%2d:%2d\n", gm.tm_mon + 1, gm.tm_mday, gm.tm_hour + 8, gm.tm_min, gm.tm_sec);
    return 0;
}
Status ShowStack(Stack S) //查看车库车辆信息
{
    int i;
    printf("***************************************************\n");
    printf("车位使用情况\n");
    if (1 == StackEmpty(S)) //车库为空
    {
        printf("停车场没有车辆!\n");
    }
    else
    {
        printf("车位\t车牌号\t进库时间\n"); //显示车库车辆信息
        for (i = 0; i <= S.top; i++)        //循环输出车库内的车辆信息
        {
            printf("%d\t", S.data[i].position);
            printf("%s\t", S.data[i].number);
            PrintDate(S.data[i].intime);
        }
        printf("\t\t\t共%d辆车", S.top + 1);
        if (MAX - 1 == S.top) //判断车库满否
        {
            printf("(车库已满)\n");
        }
        else
        {
            printf("(还可以停放%d辆车)\n", MAX - 1 - S.top);
        }
    }
    printf("***************************************************\n");
    return 0;
}
Status ShowLQueue(LQueue Q) //查看过道车辆信息
{
    printf("###################################################\n");
    if (1 == LQueueEmpty(Q)) //过道为空
    {
        printf("过道上没有车辆在等待!\n");
    }
    else //过道不为空,遍历过道队列
    {
        LQueuePtr p;
        p = Q.front->next;
        printf("过道使用情况!\n");
        printf("车牌号\t进入时间\n");
        while (NULL != p)
        {
            printf("%s\t", p->data.number);
            PrintDate(p->data.intime);
            p = p->next;
        }
    }
    printf("过道上等候车辆数量为:%d\n", LQueueLength(Q));
    printf("###################################################\n");
    return 0;
}
Status ShowLQ(LQueue P) //查看已经离开车辆的信息
{
    printf("***************************************************\n");
    if (1 == LQueueEmpty(P)) //无车辆离开
    {
        printf("目前无离开车辆!\n");
    }
    else //有车辆离开
    {
        LQueuePtr p;
        p = P.front->next;
        printf("已经离开车辆信息如下:\n");
        printf("车牌号\t停车时长(秒)\n");
        while (NULL != p)
        {
            printf("%s\t", p->data.number);
            printf("%d\n", p->data.time);
            p = p->next;
        }
    }
    printf("***************************************************\n");
    return 0;
}
Status ShowAll(Stack S, LQueue Q, LQueue P) //查看整个停车场所以车辆信息(包括已经离开的)
{
    ShowStack(S);
    ShowLQueue(Q);
    ShowLQ(P);
    printf("按回车键继续...\n");
    getchar();
    return 0;
}
Status Search(Stack S, LQueue P) //按车牌号搜索车辆是否来过停车场,是否还在停车场
{
    CAR car;
    LQueuePtr p;
    int a = 0, b = 0, i; //通过判断a,b的值来判断该搜索地点有没有该车牌号的车辆信息
    printf("请输入车牌号:");
    scanf("%s", car.number);
    getchar();
    if (0 == StackEmpty(S)) //在停车场栈搜索
    {
        for (i = S.top; i >= 0; i--)
        {
            if (0 == strcmp(car.number, S.data[i].number))
            {
                a = 1;
                printf("该车辆在停车场内! ");
                printf("该车进入停车场的时间为:");
                PrintDate(S.data[i].intime);
                break;
            }
        }
    }
    if (0 == LQueueEmpty(P) && 0 == a) //在离开车辆队列里搜索
    {
        p = P.front->next; //p指向第一个车辆数据结点
        for (p; p != NULL; p = p->next)
        {
            if (0 == strcmp(car.number, p->data.number))
            {
                b = 1;
                printf("该车已离开停车场! ");
                printf("停车时长(秒):%d\n", p->data.time);
                break;
            }
        }
    }
    if (0 == a && 0 == b)
    {
        printf("该车没来过本停车场!\n");
    }
    printf("按回车键继续...\n");
    getchar();
    return 0;
}
Status Reach(Stack *S, LQueue *Q) //入库
{
    CAR car;
    int i;
    struct tm *gm;    //定义tm结构体类型的指针gm
    time_t gt;        //定义time_t类型的时间变量mt
    time(&gt);        //time()函数获得机器时间存入时间变量mt
    gm = gmtime(&gt); //gmtime()函数将时间变量mt中的机器时间转换成真实世界所使用的时间日期
    car.intime = *gm; //获得车辆进入时间
    printf("请输入车牌号:");
    scanf("%s", car.number);
    getchar();
    if (0 == StackEmpty(*S)) //在停车场内搜索是否存在该车牌号,若存在,则需要重新输入
    {
        for (i = S->top; i >= 0; i--)
        {
            if (0 == strcmp(car.number, S->data[i].number))
            {
                printf("该车牌号已存在,请重新输入车牌号:");
                scanf("%s", car.number);
                getchar();
                break;
            }
        }
    }

    if (0 == StackFull(*S) && 1 == LQueueEmpty(*Q)) //栈未满,入栈
    {
        car.position = S->top + 2;
        PushStack(S, car);
        ShowStack(*S);
    }
    else if (1 == StackFull(*S)) //栈满,入队列
    {
        printf("提示:车位已满,只有先停放在过道上!\n");
        car.position = MAX;
        PushLQueue(Q, car);
        ShowStack(*S);
        ShowLQueue(*Q);
    }
    printf("按回车键继续...\n");
    getchar();
    return 0;
}
Status PrintBill(CAR car) //输出离开车库时的车辆信息
{
    printf("***************************************************\n");
    printf("***账单***\n");
    printf("车牌号:%s\n", car.number);
    printf("停车位置:%d\n", car.position);
    printf("进入时间:");
    PrintDate(car.intime);
    printf("离开时间:");
    PrintDate(car.outtime);
    printf("停车时长(秒):%d\n", car.time);
    printf("停车费用(元):%d\n", car.cost);
    printf("***************************************************\n");
    printf("按回车键继续...\n");
    getchar();
    return 0;
}
Status Leave(Stack *S, LQueue *Q, LQueue *P) //离开车库
{
    struct tm *gm;
    time_t mt;
    Stack R;       //定义一个让路栈R
    InitStack(&R); //初始化让路栈
    CAR car;
    int i, pos; //pos变量为要离开车辆的车位
    if (1 == StackEmpty(*S))
    {
        printf("所有车位是空的,没有车辆需要离开!\n");
    }

    else
    {
        printf("此时车位使用情况如下:\n");
        ShowStack(*S);
        printf("请输入需要离开车辆的车位:");
        scanf("%d", &pos);
        getchar();

        if (pos > 0 && pos <= S->top + 1) //输入车位的值在0到S->top+1之间
        {
            for (i = S->top + 1; i > pos; i--) //将车库内车位 大于 需要离开车辆的车位 的车辆车位信息减1 push入让路栈
            {
                car = PopStack(S);
                car.position = car.position - 1;
                PushStack(&R, car);
            }
            car = PopStack(S);
            time(&mt);
            gm = gmtime(&mt);
            car.outtime = (*gm);                                   //对应车位pos的车辆离开时间
            car.time = mktime(&car.outtime) - mktime(&car.intime); //调用mktime()函数计算车辆停留时间(秒)
            car.cost = (car.time / 3600 + 1) * PRICE;              //计算车辆需要缴纳的费用
            PrintBill(car);                                        //打印账单
            PushLQueue(P, car);                                    //将离开的车辆信息存入队列P中
            while (0 == StackEmpty(R))                             //若让路栈内有车辆,将车辆重新push入车库
            {
                car = PopStack(&R);
                PushStack(S, car);
            }
            while (0 == LQueueEmpty(*Q)) //若过道有车辆等候,将第一个等候车辆push入车库
            {
                car = PopLQueue(Q);
                time(&mt);
                gm = gmtime(&mt);
                car.intime = (*gm);
                PushStack(S, car);
                break;
            }
        }
        else
        {
            printf("输入车位错误!\n");
            printf("按回车键继续...\n");
            getchar();
        }
    }
    return 0;
}
char *menu[] = { //菜单显示软件具备的功能
    "******欢迎使用停车场系统******\n",
    " *1.驶入停车场\n",
    " *2.离开停车场\n",
    " *3.查看停车场信息\n",
    " *4.搜索车辆信息\n"
    " *0.退出系统\n",
    "******************************\n"};

char Menu(char *str[], int len) //菜单函数 返回用户选择的功能号(整型)
{
    int i;
    char sel;
    for (i = 0; i < len; i++) //打印菜单
    {
        printf("%s", str[i]);
    }
    printf("提示:本停车场共%d个车位,停满后的车辆停在过道上!\n", MAX);
    printf("收费标准:停在停车场的车辆 %.2f元/小时(不足一小时按一小时算),停在过道上的车辆不收费!\n", PRICE);
    printf("请输入您的选择:");
    scanf(" %c", &sel);
    getchar();
    return sel;
}

3、功能函数调用,实现系统运行。

int main(int argc, char *agrv[])
{
    Stack S;
    LQueue Q, P;
    char sel;
    InitStack(&S);  //初始化停放栈
    InitLQueue(&Q); //初始化过道等候队列
    InitLQueue(&P); //初始化存放离开车辆信息队列
    while (1)
    {
        sel = Menu(menu, 7); //调用菜单函数
        switch (sel)
        {
        case '1':
            Reach(&S, &Q); //进入停车场
            break;
        case '2':
            Leave(&S, &Q, &P); //离开停车场
            break;
        case '3':
            ShowAll(S, Q, P); //查看停车场信息
            break;
        case '4':
            Search(S, P); //查找车辆信息
            break;
        case '0':
            printf("欢迎您的下次使用!\n按回车键退出...\n");
            getchar();
            exit(0);
            break;
        default:
            printf("错误输入!\n按回车键继续...\n");
            getchar();
            break;
        }
    }
    return 0;
}

4、运行结果。

    1> 车辆进入停车场

    2> 查看停车场信息

Logo

快速构建 Web 应用程序

更多推荐