问题描述:停车场是一个能放 n
辆车的狭长通道,只有一个大门,汽车按到达的先后次序停放。若车场满了,车要在门外的便道上等候,一旦有车走,则便道上第一辆车进入。当停车场中的车离开时,由于通道窄,在它后面的车要先退出,待它走后依次进入。汽车离开时按停放时间收费。
基本功能要求:
1)建立三个数据结构分别是:停放队列,让路栈,等候队列
2)输入数据模拟管理过程,数据(入或出,车号)。
main.c:
#define _CRT_SECURE_NO_WARNINGS //兼容VS2017
/**********************************************************
兼容 vc6.0 、vs2010 、 vs2017 采用的 c89 标准
兼容 Windows 和 Linux 系统
问题描述:停车场是一个能放 n 辆车的狭长通道,只有一个大门,
汽车按到达的先后次序停放。若车场满了,车要在门外的便道上等候
,一旦有车走,则便道上第一辆车进入。当停车场中的车离开时,由
于通道窄,在它后面的车要先退出,待它走后依次进入。汽车离开
时按停放时间收费。
基本功能要求:
1)建立三个数据结构分别是:停放队列,让路栈,等候队列
2)输入数据模拟管理过程,数据(入或出,车号)。
***********************************************************/
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include "park.h"
#define EXIT '5'
#define Price 1 // 单价可以自己定义n
#define SYSTEM_FILE_NAME "parking_management_system.data"
// 保存系统文件
void save_system(Pavement *p_pavement, Stopping *p_stopping, Buffer *p_buffer, Car *p_car, char *file_name)
{
FILE *fp;
LinkPavement *temp;
int i;
fp = fopen(file_name, "wb");
if (fp)
{
fwrite(p_stopping, sizeof(Stopping), 1, fp);
fwrite(p_buffer, sizeof(Buffer), 1, fp);
fwrite(p_car, sizeof(Car), 1, fp);
fwrite(p_pavement, sizeof(Pavement) - sizeof(void *), 1, fp);
temp = p_pavement->head;
for (i = 0; i < MAX_PAVE && temp!=NULL; i++)
{
fwrite(temp, sizeof(LinkPavement) - sizeof(void *), 1, fp);
temp = temp->next;
}
fclose(fp);
}
else
{
fprintf(stderr, "%s", "Error: 无法打开或者创建文件\n");
}
}
int main()
{
int i;
Pavement *p_pavement;
LinkPavement *temp,buf_link;
Stopping stopping = { 0 };
Buffer buffer = { 0 };
Car car = { 0 };
char ch;
FILE *fp = NULL;
char opt = '\0';//专门用来储存选项
p_pavement = (Pavement *)malloc(sizeof(Pavement));
memset(p_pavement, 0, sizeof(Pavement));
fp = fopen(SYSTEM_FILE_NAME, "rb");
if (fp)
{
printf("%s",
"检测到系统数据库文件,即将载入文件\n"
"您可以输入 n 取消载入,或者直接回车载入系统数据库文件\n"
">>> ");
fflush(stdout);
setbuf(stdin, NULL); // 清空输入流流,防止数据污染
if (fgetc(stdin) != 'n')
{
fread(&stopping, sizeof(Stopping), 1, fp);
fread(&buffer, sizeof(Buffer), 1, fp);
fread(&car, sizeof(Car), 1, fp);
fread(p_pavement, sizeof(Pavement) - sizeof(void *), 1, fp);
if (-1 != fread(&buf_link, sizeof(LinkPavement) - sizeof(void *), 1, fp))
{
p_pavement->head = (LinkPavement *)malloc(sizeof(LinkPavement));
memcpy(p_pavement->head, &buf_link, sizeof(LinkPavement) - sizeof(void *));
}
temp = p_pavement->head;
for (i = 0; i < MAX_PAVE-1 ; i++)
{
if (-1 == fread(&buf_link, sizeof(LinkPavement) - sizeof(void *), 1, fp))
{
break;
}
temp->next = (LinkPavement *)malloc(sizeof(LinkPavement));
memcpy(temp->next, &buf_link, sizeof(LinkPavement) - sizeof(void *));
}
temp->next = NULL;
}
else
{
// 初始化
stopping.top = -1;
buffer.top = 0;
p_pavement->count = 0;
p_pavement->head = NULL;
}
setbuf(stdin, NULL);// 清空输入流流,防止输入流溢出
fclose(fp);
}
else
{
// 初始化
stopping.top = -1;
buffer.top = 0;
p_pavement->count = 0;
p_pavement->head = NULL;
}
while (opt != EXIT)
{
#ifdef _WIN32 // 兼容MSVC编译器
system("cls");
#elif __GNUC__ // 兼容gcc编译器
system("clear");
#endif
// 主界面函数
printf("\t*******************目前停车场状况***********************\n");
printf("\t停车场共有%d个车位,当前停车场共有%d辆车,等候区共有%d辆车\n", MAX_STOP, stopping.top + 1, p_pavement->count);
printf(
"\t********************************************************\n"
"\t---------------欢迎使用停车管理系统---------------\n"
"\t请输入功能号进行任务选择: \n"
"\n"
"\t* 1.停车 *\n"
"\t* 2.离开 *\n"
"\t* 3.当前状态 *\n"
"\t* 4.保存系统数据库文件 *\n"
"\t* 5.退出 *\n"
"\t-----------------------------------------------------\n");
fprintf(stdout, "%s", ">>> ");
fflush(stdout);// 刷新输入流,否则在部分系统不会自动刷新
opt = fgetc(stdin); // 从输入流中直接获取
setbuf(stdin, NULL); // 刷新输入流,防止输入流溢出
switch (opt)
{
case '1':
car_come(p_pavement, MAX_PAVE, &stopping);
break;
case '2':
car_leave(p_pavement, &stopping, &buffer, &car, Price, MAX_PAVE, MAX_STOP);
break;
case '3':
Display(&stopping, Price);
break;
case '4':
save_system(p_pavement, &stopping, &buffer, &car, SYSTEM_FILE_NAME);// 保存系统文件
printf("保存成功!\n\n");
break;
case EXIT:
break;
default:
fprintf(stderr, "%s", "您的输入有误,请重新输入\n"); // 输入到错误流中
break;
}
if (opt != EXIT)
{
fprintf(stdout, "%s", "按下 Enter 键返回到主系统\n");
fflush(stdout);// 刷新输入流流,否则在部分系统不会自动刷新
while((ch=getchar())!='\n'&&ch!=EOF);
fgetc(stdin);
setbuf(stdin, NULL); // 刷新输入流,防止输入流溢出
}
}
save_system(p_pavement, &stopping, &buffer, &car, SYSTEM_FILE_NAME); // 保存系统文件
printf("\n自动保存系统数据库文件成功\n");
printf("欢迎下次使用,再见!\n");
free_link_pavement(p_pavement);
return 0;
}
park.h
#ifndef PARK
#define PARK
#define MAX_STOP 4
#define MAX_PAVE 4
// 汽车信息
typedef struct
{
long long timeIn; // 进入停车场时间
long long timeOut; // 离开停车场时间
char plate[0x100];
// 汽车牌照号码,定义一个字符指针类型
}Car;
// 停放栈(用于停放车辆)
typedef struct
{
Car Stop[MAX_STOP]; // 用于停放车辆的栈
int top; // 标记栈顶位置
}Stopping;
// 等候链队列
typedef struct LinKPavement
{
Car car;
struct LinKPavement *next; // 等候停车的队列
}LinkPavement;
// 等候队列链首
typedef struct
{
int count; // 用来指示队中的数据个数
int max_pave;
struct LinKPavement *head; // 等候停车的队列
}Pavement;
// 让路栈
typedef struct
{
Car Help[MAX_STOP]; // 用于让路的队列
int top; // 标记站定位置
}Buffer;
// 释放链队列
void free_link_pavement(Pavement *p_pavement);
void stop_to_pave(Pavement *p_pavement, int max_pave, char *licence_plate); // 车停入便道
void car_come(Pavement *p_pavement, int max_pave, Stopping *p_stopping); // 车停入停车位
void stop_to_buff(Pavement *p_pavement, Stopping *p_stopping, Buffer *p_buffer, Car *p_car, char *info, int price, int max_pave, int max_stop); // 车进入让路栈
void car_leave(Pavement *p_pavement, Stopping *p_stopping, Buffer *p_buffer, Car *p_car, int price, int max_pave, int max_stop); // 车离开
void Display(Stopping *p_stopping, int price); // 显示车辆信息
#endif //PARK
park.c
#define _CRT_SECURE_NO_WARNINGS //兼容VS2017
#include <stdlib.h>
#include <stdio.h>
#include <time.h> // 包含时间函数的头文件
#include <string.h>
#include "park.h"
void free_link_pavement(Pavement *p_pavement)
{
LinkPavement *temp,*head;
int i,max_pave;
head = p_pavement->head;
max_pave = p_pavement->max_pave;
free(p_pavement);
for (i = 0; i < max_pave && head !=NULL; i++)
{
temp = head;
head = head->next;
free(temp);
}
}
void stop_to_pave(Pavement *p_pavement, int max_pave, char *licence_plate) // 车停入便道
{
LinkPavement *link;
// 判断队满
if (p_pavement->count>=max_pave)
{
printf("便道已满,请下次再来\n");
}
else
{
link = (LinkPavement *)malloc(sizeof(LinkPavement));// 分配空间
memset(link, 0, sizeof(LinkPavement));// 清零
strcpy(link->car.plate, licence_plate); // 车进入便道
link->next = p_pavement->head;
p_pavement->head = link;
(p_pavement->count)++; // 计数器加1
printf("牌照为 %s 的汽车停入便道\n", licence_plate);
}
}
void car_come(Pavement *p_pavement, int max_pave, Stopping *p_stopping) // 车停入停车位
{
time_t t1;
long int t;
char buf[0x100] = { 0 }; // 用于缓存字符
char time_str[0x100] = { 0 };
char ch;
printf("请输入即将停车的车牌号:"); // 输入车牌号
#ifdef __GNUC__
while ((ch = getchar()) != '\n'&&ch != EOF); // 清空输入流流,防止数据污染
#endif // __GNUC__
fgets(buf, 0x100, stdin); // 防止溢出
buf[strlen(buf) - 1] = '\0';
setbuf(stdin, NULL);// 刷新输入流流,防止输入流流溢出
if (p_stopping->top >= MAX_STOP - 1) // 如果停车位已满,停入便道
{
stop_to_pave(p_pavement, max_pave, buf); // 停入便道
}
else
{
p_stopping->top++; // 停车位栈顶指针加1
t = (long long)time(&t1); // 记录进入停车场的时间
strftime(time_str, sizeof(time_str), "%Y-%m-%d %X", localtime(&t1));
p_stopping->Stop[p_stopping->top].timeIn = t;
strcpy(p_stopping->Stop[p_stopping->top].plate, buf); // 将车牌号登记
printf("牌照为 %s 的汽车停入停车位的 %d 车位, 当前时间: %s\n", buf, p_stopping->top + 1, time_str);
}
return;
}
void stop_to_buff(Pavement *p_pavement, Stopping *p_stopping, Buffer *p_buffer, Car *p_car, char *info, int price, int max_pave, int max_stop) // 车进入让路栈
{
time_t t1;
int i, count;
long long t;
char time_str[0x100] = { 0 };
LinkPavement *temp1, *temp2;
// 停车位栈压入临时栈,为需要出栈的车辆让出道
while (p_stopping->top >= 0)
{
if (0 == strcmp(p_stopping->Stop[p_stopping->top].plate, info))
{
break;
}
// 让出的车进入让路栈
strcpy(p_buffer->Help[(p_buffer->top)++].plate, p_stopping->Stop[p_stopping->top].plate);
printf("牌照为 %s 的汽车暂时退出停车场\n", p_stopping->Stop[(p_stopping->top)--].plate);
}
// 如果停车位中的车都让了道,说明停车位中无车辆需要出行
if (p_stopping->top < 0)
{
printf("停车位上无此车消息\n");
}
else
{
printf("牌照为 %s 的汽车从停车场开走\n", p_stopping->Stop[p_stopping->top].plate);
t = time(&t1);
p_car->timeOut = t; // 标记离开停车场的时间
strftime(time_str, sizeof(time_str), "%Y-%m-%d %X", localtime(&t1));
printf("\n离开时间%s\n需付%lld元\n\n", time_str, price * (p_car->timeOut - p_stopping->Stop[p_stopping->top].timeIn));
(p_stopping->top)--;
}
// 将让路栈中的车辆信息压入停车位栈
while (p_buffer->top > 0)
{
strcpy(p_stopping->Stop[++(p_stopping->top)].plate, p_buffer->Help[--(p_buffer->top)].plate);
printf("牌照为 %s 的汽车停回停车位 %d 车位\n", p_buffer->Help[p_buffer->top].plate, p_stopping->top);
}
// 从便道中 -> 停车位
while (p_stopping->top < max_stop - 1)
{
if (p_pavement->count <= 0) // 判断队列是否为空
{
break;
} // 不为空,将便道中优先级高的车停入停车位
else
{
temp1 = p_pavement->head;
count = --(p_pavement->count);
for (i = 0; i < count-1; i++)
{
temp1 = temp1->next;
}
if (count == 0)
{
printf("牌照为 %s 的汽车从便道中进入停车位的 %d 车位\n", temp1->car.plate, p_stopping->top);
strcpy(p_stopping->Stop[++(p_stopping->top)].plate, temp1->car.plate);
t = (long long)time(&t1); // 记录进入停车场的时间
p_stopping->Stop[p_stopping->top].timeIn = t;
p_pavement->head = NULL;
free(temp1);
}
else
{
temp2 = temp1;
temp1 = temp1->next;
printf("牌照为 %s 的汽车从便道中进入停车位的 %d 车位\n", temp1->car.plate, p_stopping->top);
strcpy(p_stopping->Stop[++(p_stopping->top)].plate, temp1->car.plate);
t = (long long)time(&t1); // 记录进入停车场的时间
p_stopping->Stop[p_stopping->top].timeIn = t;
free(temp1);
temp2->next = NULL;
}
}
}
}
void car_leave(Pavement *p_pavement, Stopping *p_stopping, Buffer *p_buffer, Car *p_car, int price, int max_pave, int max_stop) // 车离开
{
char buf[0x100] = { 0 }; // 用于缓存字符
char ch;
printf("请输入即将离开的车牌号:\t");
#ifdef __GNUC__
while ((ch = getchar()) != '\n'&&ch != EOF); // 清空输入流流,防止数据污染
#endif // __GNUC__
fgets(buf, 0x100, stdin); // 防止溢出
buf[strlen(buf) - 1] = '\0';
setbuf(stdin, NULL); // 清空输入流流,防止输入流溢出
if (p_stopping->top < 0) // 判断停车位是否有车辆信息
{
printf("车位已空,无车辆信息!\n");
}
else
{
stop_to_buff(p_pavement, p_stopping, p_buffer, p_car, buf, price, max_pave, max_stop);
}
}
void Display(Stopping *p_stopping, int price)
{
int i;
int count;
time_t t1;
long int t;
i = p_stopping->top;
count = 1;
if (-1 == i)
{
printf("停车场为空\n");
}
t = time(&t1); // 标记显示时的时间
while (i != -1)
{
printf("%d:\n", count);
printf("\t车牌号:\t%s\n", p_stopping->Stop[i].plate);
printf("\t停放时间:\t%lld秒\n", t - p_stopping->Stop[i].timeIn);
printf("\t当前所需支付金额:\t%lld元\n", price * (t - p_stopping->Stop[i].timeIn) / 10);
puts("");
i--;
count++;
}
}