停车场项目实战
停车场是一个能放 n 辆车的狭长通道,只有一个大门,汽车按到达的先后次序停放。若车场满了,车要停在门外的便道上等候,一旦有车走,则便道上第一辆车进入。当停车场中的车离开时,由于通道窄,在它后面的车要先退出,待它走后在依次进入。汽车离开时按停放时间收费。
基本功能要求:
(1)建立三个数据结构分别是:停放栈、让路栈、等候队列。
(2)输入数据模拟管理过程,数据(入或出,车号)
功能描述:进车登记、出车登记、按车牌号查询停车车辆信息、查询出入车记录、
查询场内车辆信息、查询等候车辆信息、退出系统。
(1)linux系统编写(链表、栈、队列);
(2)进车登记:登记车牌号以及入场时间;
(3)出车登记:计算出停车时间,记录车辆车牌;
(4)按车牌号查询车辆信息:停车时间,是否来过停车场,是否还在停车场
(5)查询出入记录:所有车辆,包括已经离开的
(6)查询场内车辆信息:列出所有场内车辆信息
(7)查询等候车辆信息:显示等候车辆数量以及所有车牌号
(8)退出系统。
基本功能要求:
(1)建立三个数据结构分别是:停放栈、让路栈、等候队列。
(2)输入数据模拟管理过程,数据(入或出,车号)
功能描述:进车登记、出车登记、按车牌号查询停车车辆信息、查询出入车记录、
查询场内车辆信息、查询等候车辆信息、退出系统。
(1)linux系统编写(链表、栈、队列);
(2)进车登记:登记车牌号以及入场时间;
(3)出车登记:计算出停车时间,记录车辆车牌;
(4)按车牌号查询车辆信息:停车时间,是否来过停车场,是否还在停车场
(5)查询出入记录:所有车辆,包括已经离开的
(6)查询场内车辆信息:列出所有场内车辆信息
(7)查询等候车辆信息:显示等候车辆数量以及所有车牌号
(8)退出系统。
项目分析:
首先,我们需要明白定义的栈和队列分别存放什么内容?
我们要定义两个栈和两个队列,分别存放停车场场内车辆信息、临时停放车辆出车、停车场外部候车队列、以及整合进出信息队列。
头文件:park.h
#ifndef _PARK_H_
#define _PARK_H_
#define SUCCESS 1000000
#define FAILURE 1000001
#define MAXSIZE 2
struct node //结点存放车辆的车牌、停车时间(月、日、时、分、秒)
{ //存放开始和结束时间用来结算金额
int month, day, hour, min, sec;
time_t start, end;
char id[10];
char Info[3];
struct node *next;
};
typedef struct node Node;
struct park //定义park栈,停车和临时停车用
{
Node *top;
int stall;
};
typedef struct park Park;
struct queue //定义队列,候车及整合进出记录用
{
Node *front;
Node *rear;
};
typedef struct queue Queue;
int StackInit(Park *s);
int QueueInit(Queue *s);
int show();
int PrintInfo();
int ParkIn(Park *s, Queue *p, Queue *record);
int ParkOut(Park *s, Park *p, Queue *sq, Queue *record);
int Inside(Park *s);
int Outside(Queue *s);
int Record(Queue *record);
int SearchInfo(Park *s, Queue *sq);
#endif
接口函数:park.c
#include <stdio.h> #include <stdlib.h> #include "park.h" #include <time.h> #include <string.h> int show() { printf("\t\t\t\t"); printf("************************************************************\n\n"); printf("\t\t\t\t"); printf("***** WELCOME TO PARKING LOT! *****\n\n"); printf("\t\t\t\t"); printf("************************************************************\n\n"); sleep(1); system("clear"); } int PrintInfo() { printf("\t\t\t\t"); printf("***********************************************************\n\n"); printf("\t\t\t\t"); printf("***1.入库登记 2.出库登记 ***\n\n"); printf("\t\t\t\t"); printf("***3.查询场内车辆信息 4.查询等待车辆信息 ***\n\n"); printf("\t\t\t\t"); printf("***5.查看出入记录 6.查询车辆信息 ***\n\n"); printf("\t\t\t\t"); printf("***7.退出 ***\n\n"); printf("\t\t\t\t"); printf("***********************************************************\n\n"); printf("\t\t\t\t"); printf("请输入你的选择:\n"); } int SetTime(Node *p, time_t t) //将系统时间转化为月、日、时、分、秒 { struct tm *pt; time(&t); pt = localtime(&t); p->month = pt->tm_mon; p->day = pt->tm_mday; p->hour = pt->tm_hour; p->min = pt->tm_min; p->sec = pt->tm_sec; } int TimeCopy(Node *s, Node *p) //获取所有进出停车场的信息时,复制时间用 { s->month = p->month; s->day = p->day; s->hour = p->hour; s->min = p->min; s->sec = p->sec; s->start = p->start; } int StackInit(Park *s) //栈的初始化 { s->top = NULL; s->stall = 0; return SUCCESS; } int QueueInit(Queue *s) //队列的初始化 { s->front = (Node *)malloc(sizeof(Node)); if(NULL == s->front) { return FAILURE; } s->rear = s->front; s->front->next = NULL; return SUCCESS; }
int QueueLength(Queue L) //求队列的长度,在下文的if语句和遍历时用到int Push(Park *s, Node *p) //往栈里加入结点 { p->next = s->top; s->top = p; return SUCCESS; }
{
int length = 0;
Node *p = L.front->next;
while(p != NULL)
{
length++;
p = p->next;
}
return length;
}
int ParkIn(Park *s, Queue *q, Queue *record) { char num[10]; //定义字符串保存车牌号 if(s->stall >= MAXSIZE) //stall表示停车场能容纳的最多车辆数 { //当大于容量时,将车移动到等候队列 Node *m = (Node *)malloc(sizeof(Node)); printf("\t\t\t\t车位已满!!!\n"); printf("\t\t\t\t请输入车牌号码,并依次排队等候!\n"); printf("\t\t\t\t"); scanf("%s", num); strcpy(m->id, num); q->rear->next = m; q->rear = m; } else if(s->stall < MAXSIZE && QueueLength(*q) == 0) { //当场内可停放且等候队列无车时直接进场 time_t t; Node *p = (Node *)malloc(sizeof(Node)); //p结点为栈内存放停车信息 Node *k = (Node *)malloc(sizeof(Node)); //k结点为队列存放停车信息 if(NULL == p || NULL == k) { return FAILURE; } printf("\t\t\t\t请输入车牌号码:\n"); printf("\t\t\t\t"); scanf("%s", num); SetTime(p, t); time(&t); p->start = t; p->next = NULL; strcpy(p->id, num); Push(s, p); s->stall++; strcpy(k->id, num); //将停车信息复制到队列中 strcpy(k->Info, "IN"); TimeCopy(k, p); k->next = NULL; record->rear->next = k; record->rear = k; } }
int ParkOut(Park *s, Park *p, Queue *queue, Queue *record) { //停车场出车部分,出车的同时如果等候队列有车,则等候队列 //车辆进场,这与上面的PARKIN部分的两个情况相弥补 Node *sp = s->top; char num[10]; int count = 0, i, total_time = 0; time_t t; printf("\t\t\t\t请输入车牌号码:\n"); printf("\t\t\t\t"); scanf("%s", num); while(sp) //遍历栈,有相同的则打印,没有相同的则提示输入有误 { if(strcmp(sp->id, num) == 0) { printf("\t\t\t\t车牌号码:%s\n", sp->id); printf("\t\t\t\t入库时间:%d月%d日%d:%d: %d\n", sp->month, sp->day, sp->hour, sp->min, sp->sec); SetTime(sp, t); time(&t); sp->end = t; total_time = sp->end - sp->start; //定义h为队列结点,存放所有出栈信息,在得到出场时间之后再保存 Node *h = (Node *)malloc(sizeof(Node)); strcpy(h->id, sp->id); TimeCopy(h, sp); h->next = NULL; strcpy(h->Info, "Leave"); record->rear->next = h; record->rear = h; printf("\t\t\t\t出库时间:%d月%d日%d:%d:%d\n", sp->month, sp->day, sp->hour, sp->min, sp->sec); printf("\t\t\t\t停车时长:%d秒 收费标准:1元/秒\n", total_time); printf("\t\t\t\t应缴纳: %d元\n", total_time); s->top = sp->next; s->stall--; break; } else { //如果没找到,先将top暂放至临时栈,等遍历一遍之后,在移回来 s->top = sp->next; sp->next = NULL; Push(p, sp); count++; } sp = s->top; } if(NULL == sp) { printf("\t\t\t\t您输入的车牌号码有误!\n"); } for(i = 0; i < count;i++) { Node *L = p->top; p->top = L->next; Push(s, L); } //这两个if部分,考虑到队列出队的特殊性,队列只有一个结点时,要将rear //重新指向front if(QueueLength(*queue) == 1 && s->stall < MAXSIZE) { char licnum[10]; time_t t; Node *p = queue->front->next; // 将队列中的候车移入停车场内 Node *h = (Node *)malloc(sizeof(Node)); queue->front->next = p->next; SetTime(p, t); time(&t); p->start = t; Push(s, p); s->stall++; queue->rear = queue->front; strcpy(h->id, p->id); TimeCopy(h, p); h->next = NULL; record->rear->next = h; record->rear = h; strcpy(h->Info, "IN"); } //当队列中有两个以上的结点时,不需要对rear进行操作 else if(QueueLength(*queue) > 1 && s->stall < MAXSIZE) { char licnum[10]; time_t t; Node *p = queue->front->next; // 将队列中的候车移入停车场内 Node *h = (Node *)malloc(sizeof(Node)); queue->front->next = p->next; SetTime(p, t); time(&t); p->start = t; Push(s, p); s->stall++; //将信息再录入到整合信息队列中,从队列进场也是一种需要录入的情况 strcpy(h->id, p->id); TimeCopy(h, p); h->next = NULL; record->rear->next = h; record->rear = h; strcpy(h->Info, "IN"); } }
int Inside(Park *s ) //打印所有在场内的车辆信息 { Node *l = s->top; while(l) { printf("\t\t\t\t车牌号:%s\n",l->id); printf("\t\t\t\t停车时间:%d月%d日%d:%d:%d\n", l->month, l->day, l->hour, l->min, l->sec); l = l->next; } } int Outside(Queue *s) //打印所有在场外的信息 { if( NULL == s->front->next) { printf("\t\t\t\t无候车车辆\n"); } Node *p = s->front->next; while(p) { printf("\t\t\t\t等待车辆信息如下:\n"); printf("\t\t\t\t车牌号:%s\n", p->id); p = p->next; } } int Record(Queue *record) //遍历输出所有整合信息,按时间排序 { Node *p = record->front->next; while(p) { printf("\t\t\t\t车牌号码:%s" ,p->id); printf(" %d月%d日%d:%d:%d %s\n",p->month, p->day, p->hour, p->min, p->sec, p->Info); p = p->next; } } int SearchInfo(Park *s, Queue *record) { char num[10]; printf("\t\t\t\t请输入您要查找的车牌号码:\n"); printf("\t\t\t\t"); scanf("%s", num); Node *p = record->front->next; while(p) { if(strcmp(p->id, num) == 0) { break; } else { p = p->next; } } if(NULL == p) { printf("无相关记录!\n"); } p = record->front->next; while(p) //遍历输出所有该车在本停车场的进出信息,并指明目前该车是否还在 { if(strcmp(p->id, num) == 0) { printf("\t\t\t\t车牌号码:%s" ,p->id); printf("\t %d月%d日%d:%d:%d %s\n",p->month, p->day, p->hour, p->min, p->sec, p->Info); p = p->next; continue; } else { p = p->next; } } Node *q = s->top; while(q) { if(strcmp(num, q->id) == 0) { printf("\t\t\t\t此车仍在停车场中\n"); break; } else { q= q->next; } } if(NULL == q) { printf("\t\t\t\t此车不在停车场中!\n"); } }
main.c
#include <stdio.h>
#include <stdlib.h>
#include "park.h"
int main()
{
show();
char choice[8] = {0};
Park InLot, OutLot;
Queue sq, rec;
if(StackInit(&InLot) != SUCCESS || StackInit(&OutLot) != SUCCESS
|| QueueInit(&sq) != SUCCESS || QueueInit(&rec) != SUCCESS)
{
printf("Init Failure\n");
}
while(1)
{
PrintInfo();
printf("\t\t\t\t");
scanf("%s", choice);
switch(atoi(&choice[0]))
{
case 1:
ParkIn(&InLot, &sq, &rec);
break;
case 2:
ParkOut(&InLot, &OutLot, &sq, &rec);
break;
case 3:
Inside(&InLot);
break;
case 4:
Outside(&sq);
break;
case 5:
Record(&rec);
break;
case 6:
SearchInfo(&InLot, &rec);
break;
case 7:
exit(1);
default:
printf("\t\t\t\tIllicit choice!\n");
}
}
return 0;
}