C编程——停车场

1、功能要求
停车场是一个能放 10 辆车的狭长通道,只有一个大门,汽车按到达的先后次序停放。若停车场满了,车要停在门外的便道上等候,一旦有车走,则便道上第一辆车进入。当停车场中的车离开时,由于通道窄,在它后面的车要先退出,待它走后再依次进入。汽车离开时按停放时间收费。

2、程序文件
I、在停车场/src目录下新建main.c、Park.c、Strack.c、Queue.c文件

// main.c
#include <stdio.h>
#include "Park.h"

int main()
{
	system("clear");
	
	// 定义:停车栈、等候队列
	Stack s;
	Queue q;
	
	// 初始化:停车栈、等候队列 
	Init_Park(&s);
	Init_Wait(&q);
	
	Menu_Operation(&s, &q);
	
	return 0;
}
// Park.c
#include <stdio.h>
// 包括rand()、srand()、abs()等函数
#include <stdlib.h>
#include <time.h>
#include "Park.h"

// 菜单界面下的操作
void Menu_Operation(Stack *s, Queue *q)
{
	if (NULL == s || NULL == q)
	{
		return;
	}
	
	char buf[10];
	
	// 停车场里的车辆数、也即车位号
	Data car_num = 0;
	
	// 停车场外等候车辆数
	Data wait_num = -1;
	
    while (1)
    { 
		Display_Menu();
		
		scanf ("%s", buf);
		system("clear");
		printf ("\n");
		
		// 停车、离开、查看、退出
        switch (buf[0])
        {
            case PARK: 
				car_num++;
				// 停车场未满,进停车栈
				if (car_num < 11)
				{
					Push_Park(s, &car_num);	
				}
				// 进等候队列
				else
				{
					Push_Wait(q, &wait_num);
					car_num--;
				}
                break;
            case LEAVE:		
				Leave_Park(s, q, &car_num, &wait_num);
				car_num--;
                break;
            case DISPLAY:
				system("clear");
			    Display_Park(s, &car_num, &wait_num);
				break;
			case EXIT:
				system("clear");
				return;
            default:
				printf ("\t\t输入指令有误,请重新输入!\n");
				sleep(1);
				system("clear");
                break;
        }
    }	
}

// 菜单界面的显示
void Display_Menu(void)
{
	printf ("\n \n \n \n \n \n \n \n");
	printf ("\t\t\t\t\t\t**************************************************\n");
	printf ("\t\t\t\t\t\t*\t\t欢迎来到同方停车场!             *\n");
	printf ("\t\t\t\t\t\t*                                                *\n");
	printf ("\t\t\t\t\t\t*\t\t   1、停车                       *\n");
	
	printf ("\t\t\t\t\t\t*\t\t   2、离开                       *\n");
	printf ("\t\t\t\t\t\t*\t\t   3、查看                       *\n");
	printf ("\t\t\t\t\t\t*\t\t   4、退出                       *\n");
	printf ("\t\t\t\t\t\t*                                                *\n");
	printf ("\t\t\t\t\t\t**************************************************\n");
	printf ("\n\t\t\t\t\t\t请输入相应指令操作:");
	
	return;
}

// 车驶离停车场
void Leave_Park(Stack *s, Queue *q, Data *car_num, Data *wait_num)
{
	if (NULL == s)
	{
		return;
	}
	
	Data num;
	// 用以存放停车栈首元素的地址
	Node_Park *tmp_park;
	// 用以存放让路站的首地址
	Node_Park *tmp_way;
	
	// 定义让路栈
	Stack way_s;
	// 初始化让路栈
	Init_Park(&way_s);
	
	system ("clear");
	
	Display_Park(s, car_num, wait_num);
	printf ("\t\t\t\t\t\t请输入离开车辆的停车位号:");
	scanf ("%d", &num);
	
	// 停车栈不为空
	while (!Empty_Park(s))
	{
		tmp_park = GetTop_Park(s);
		
		Data park_space_num = tmp_park->park_space_num;
		
		if (num == park_space_num)
		{
			system ("clear");
			printf ("\t\t\t\t\t\t\t停车位 %d 上的车已离开!\n\n", num);
			
			printf ("\t\t\t\t\t\t\t车牌号为:");
			printf ("%d\n", s->top->park_plate_num);
			
			// time_t park_t = s->top->park_t;
			// time(&park_t);
			struct tm *display_park_t = localtime(&s->top->park_t);
			
			printf ("\t\t\t\t\t\t\t停车时间:");
			printf ( "%d/%d/%d %d:%d:%d\n",
					display_park_t->tm_year+1900, display_park_t->tm_mon + 1, display_park_t->tm_mday, 
					display_park_t->tm_hour,      display_park_t->tm_min,     display_park_t->tm_sec);
			
			time_t leave_t;
			time(&leave_t);
			struct tm *display_leave_t = localtime(&leave_t); 
			
			printf ("\t\t\t\t\t\t\t离开时间:");
			printf ( "%d/%d/%d %d:%d:%d\n",
					display_leave_t->tm_year+1900, display_leave_t->tm_mon + 1, display_leave_t->tm_mday, 
					display_leave_t->tm_hour,      display_leave_t->tm_min,     display_leave_t->tm_sec);

			Data cost = difftime(leave_t, s->top->park_t);  

			printf ("\t\t\t\t\t\t\t停车时长:%d s\n\n" , cost);
			printf ("\t\t\t\t\t\t\t您好,此次需支付的停车费用为 %d 元!\n\n", cost/10 + 1);
									  
			// 将停车栈车辆信息弹出
			Pop_Park(s);
			
			// 把让路栈里的车辆信息导入停车栈
			while (!Empty_Park(&way_s))
			{
				Node_Park *node = (Node_Park *)malloc(sizeof(Node_Park)/sizeof(char));					
				
				// 获取让路栈里首辆车的地址
				tmp_way = GetTop_Park(&way_s);
				
				// 将停车栈中的每辆车的信息存到让路栈中
				node->park_t         = tmp_way->park_t;
				node->park_space_num = tmp_way->park_space_num - 1; 
				node->park_plate_num = tmp_way->park_plate_num;
			
				node->next = s->top;
				s->top = node;

				Pop_Park(&way_s);
			}
			
			// 获取等候队列的首辆车信息,并存入停车栈
			// 停车场外等候车辆数
			if ( *wait_num > -1 )
			{
				Data way_plate = GetTop_Wait(q);

				Node_Park *node_2 = (Node_Park *)malloc(sizeof(Node_Park)/sizeof(char));
				
				if (NULL == node_2)
				{
					return;
				}
				
				time_t t2;
				struct tm *lt2;
				time (&t2);
				
				lt2 = localtime (&t2);
				
				printf ("\t\t\t\t\t\t	车牌号为 %d 的车已进入同方停车场!", way_plate);

				Pop_Wait(q);
				
				break;
			}	
			
			// 用于跳出while (!Empty_Park(s))循环
			break;
		}
		else
		{
			// 压入让路栈
			Push_Way(tmp_park, &way_s);
			// 释放停车站
			Pop_Park(s);
			//*appoint_space_num--;
		}	
	}
	
	return;	
}

// 让路栈:存放从停车栈中倒出的车辆信息
void Push_Way(Node_Park *s, Stack *way_s)
{
	// 为让路栈元素分配空间
	Node_Park *node = (Node_Park *)malloc(sizeof(Node_Park)/sizeof(char));
	
	if (NULL == node)
	{
		return;
	}
	
	// 将停车栈中的每辆车的信息存到让路栈中
	node->park_t = s->park_t;
	node->park_space_num = s->park_space_num; 
	node->park_plate_num = s->park_plate_num;
	
	node->next = way_s->top;
	way_s->top = node;
}

// 查看停车场的车辆信息
void Display_Park(Stack *s, Data *car_num, Data *wait_num)
{
	if (NULL == s)
	{
		return;
	}
	
	if (Empty_Park(s) == TRUE)
	{
		// 程序退出
		exit(-1);
	} 
	
	Node_Park *tmp = s->top;
	
	printf ("\n\n\t\t\t\t\t\t停车位\t\t车牌号\t\t    停车时间\n");
	
	while(tmp)
	{
		struct tm *display_park_t = localtime (&tmp->park_t);
		
		printf ("\t\t\t\t\t\t  %d\t\t%d", tmp->park_space_num, tmp->park_plate_num);
		printf ("\t\t");
		printf ( "%d/%d/%d %d:%d:%d\n",
				display_park_t->tm_year+1900, display_park_t->tm_mon + 1, display_park_t->tm_mday, 
				display_park_t->tm_hour,      display_park_t->tm_min,     display_park_t->tm_sec);
		
		tmp = tmp->next;
	}
	
	printf ("\n\t\t\t\t\t\t同方停车场内共有 %d 辆车!\n\n", *car_num);
	
	if (*car_num == 10 && *wait_num > -1)
	{
		printf ("\t\t\t\t\t\t同方停车场外共有 %d 辆等候车辆!\n\n", *wait_num + 1);
	}
	
	return; 
}


// Strack.c
// 链式栈

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "Park.h"

// 初始化栈
void Init_Park(Stack *s)
{
	if (NULL == s)
	{
		return;
	}
	
	// 把s当作头结点来使用,即相当于head
	s->top = NULL;

	return;
}

// 判断空栈
BOOL Empty_Park(Stack *s)
{
	if (NULL == s)
	{
		return FALSE;
	}
	
	if (NULL == s->top)
	{
		return TRUE;
	}
	
	return FALSE;
}
	
// 入停车栈
void Push_Park(Stack *s, Data *car_num)
{
	if (NULL == s)
	{
		return;
	}
	
	// 头插
	Node_Park *node = (Node_Park *)malloc(sizeof(Node_Park)/sizeof(char));
	
	if (NULL == node)
	{
		return;
	}
	
	// 将当前输出的停车时间保存在t中
	time_t t;
	time(&t);
	struct tm *now_t = localtime (&t);
	
	srand((unsigned int)time(NULL));
	Data rand_plate_num = rand() % 90000 + 10000;
	
	// 保存:
	// lt:时间
	// parking_space_num:停车位号
	// plate_number:随机生成5位的车牌号
	node->park_t = t;
	node->park_space_num = *car_num;
	node->park_plate_num = rand_plate_num;
	
	node->next = s->top;
	s->top = node;
	
	// 输出车辆信息
	printf ("\t\t\t\t\t\t停车成功!\n");
	printf ("\t\t\t\t\t\t车位号:%d\n", node->park_space_num);
	printf ("\t\t\t\t\t\t车牌号:%d\n", node->park_plate_num);
	printf ("\t\t\t\t\t\t停车时间:");
	printf ( "%d/%d/%d %d:%d:%d\n\n",
					now_t->tm_year + 1900, now_t->tm_mon, now_t->tm_mday, 
					now_t->tm_hour, now_t->tm_min, now_t->tm_sec);
	
	return;
}

// 出栈
void Pop_Park(Stack *s)
{
	if (NULL == s)
	{
		return;
	}
	
	if (Empty_Park(s) == TRUE)
	{
		return;
	}
	
	Node_Park *tmp = s->top;
	s->top = tmp->next;
	free(tmp);
}

// 获取栈顶元素的地址
Node_Park *GetTop_Park(Stack *s)
{
	if (NULL == s)
	{
		return 0;
	}
	 
	if (Empty_Park(s) == TRUE)
	{
		// 程序退出
		exit(-1);
	}
	
	// 返回指向首元素的地址
	return s->top;
}

// Queue.c
// 链式队列

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "Park.h"

// 初始化等候队列
void Init_Wait(Queue *q)
{
	if (NULL == q)
	{
		return;
	}
	
	// 初始化时,均指向队头。即此时为空队列
	q->front = NULL;
	q->rear  = NULL;
}

// 判断空队列
BOOL Empty_Wait(Queue *q)
{
	if (NULL == q)
	{
		return FALSE;
	}
	
	if (NULL == q->front)
	{
		return TRUE;
	}
	
	return FALSE;
}

// 入等候队列
void Push_Wait(Queue *q, Data *wait_num)
{
	if (NULL == q)
	{
		return;
	}
	
	static Data count = 0;
	srand((unsigned int)time(NULL));
	Data rand_plate_num = rand() % 90000 + 10000;
	
	Node_Wait *node = (Node_Wait *)malloc(sizeof(Node_Wait)/sizeof(char));
	
	if (NULL == node)
	{
		return;
	}
	
	// 等候队列里的车辆信息只有车牌号
	node->wait_plate_num = rand_plate_num;
	node->next = NULL;
	
	system("clear");
	printf ("\n\n\t\t\t\t\t\t同方停车场已满!\n");
	printf ("\t\t\t\t\t\t请车牌号为:%d 的车辆暂进入等候队列!\n", node->wait_plate_num);
	
	*wait_num += 1;
	printf ("\t\t\t\t\t\t您前方共有 %d 辆等候车辆!\n\n", *wait_num);
	
	// 入队列,为空时需单独考虑
	if (q->rear != NULL)
	{
		q->rear->next = node;
		q->rear = node;
	}
	else
	{
		q->rear = node;
		q->front = node;	
	}	
}

// 从等候队列出
void Pop_Wait(Queue *q)
{
	if (NULL == q)
	{
		return;
	}
	
	// 判断空队列
	if (TRUE == Empty_Wait(q))
	{
		return;
	}
	
	Node_Wait *tmp = q->front;
	q->front = tmp->next;
	free(tmp);
	
	if (NULL == q->front)
	{
		q->rear = NULL;
	}
}

// 获取等候队列顶元素的内容:车牌
Data GetTop_Wait(Queue *q)
{
	if (NULL == q)
	{
		return 0;
	}
	
	if (TRUE == Empty_Wait(q))
	{
		exit(-1);
	}
	
	return q->front->wait_plate_num;
}

II、在停车场/include目录下新建Park.h文件

// Paki.h
#ifndef _PARK_H_
#define _PARK_H_

#include <time.h>

//车位10个
#define SIZE 10

enum menu{PARK = '1', LEAVE, DISPLAY, EXIT};

typedef int Data; 
typedef enum {FALSE, TRUE, ERROR} BOOL;

// 停车栈
typedef struct _node_park
{
	// 停车位 1-10 不可变
	Data park_space_num;
	// 车牌号 随机生成的5位数 
	Data park_plate_num;
	// 存放时间:1900到现在的秒数
	time_t park_t;
	
	struct _node_park *next;
}Node_Park;

// 把s当作头结点  
typedef struct _stack
{
	Node_Park *top;
}Stack;

// 等候队列
typedef struct _node_wait
{
	Data wait_plate_num;
	struct _node_wait *next;
}Node_Wait;

typedef struct _queue
{
	Node_Wait *front;
	Node_Wait *rear;
}Queue;

// 菜单界面下的操作
void Menu_Operation(Stack *s, Queue *q);

// 菜单界面的显示
void Display_Menu(void);

// 车驶离停车场
void Leave_Park(Stack *s, Queue *q, Data *car_num, Data *wait_num);

// 让路栈:存放从停车栈中倒出的车辆信息
void Push_Way(Node_Park *s, Stack *way_s);

// 查看停车场的车辆信息
void Display_Park(Stack *s, Data *car_num, Data *wait_num);


// 初始化栈
void Init_Park(Stack *s);

// 判断空栈
BOOL Empty_Park(Stack *s);

// 入停车栈
void Push_Park(Stack *s, Data *car_num);

// 出栈
void Pop_Park(Stack *s);

// 获取栈顶元素的地址
Node_Park *GetTop_Park(Stack *s);

// 初始化等候队列
void Init_Wait(Queue *q);

// 判断空等候队列
BOOL Empty_Wait(Queue *q);

// 入等候队列
void Push_Wait(Queue *q, Data *wait_num);

// 出等候队列
void Pop_Wait(Queue *q);

// 获取等候队列顶元素
Data GetTop_Wait(Queue *q);

#endif // _PARK_H
	

III、在停车场目录下新建Makefile文件

src1 = $(wildcard ./src/*.c) 	
obj1 = $(patsubst ./src/%.c, ./obj/%.o, $(src1))  
	
target = ./bin/a.out
all:$(target)
	
$(target):$(obj1)
	gcc $(^) -o $(@)  

$(obj1):./obj/%.o:./src/%.c	
	gcc -c $(^) -I ./include -o $(@) -g

.PHONY:clean all
clean:
	-rm -rf $(target) $(obj1)	

3、测试结果

猜你喜欢

转载自blog.csdn.net/ypjsdtd/article/details/85045546