(代码很乱,也没什么注释,调试信息也没删,真心不是给别人看的东西,等标题上的草稿两字没了再看也不迟。)(注:标题带有“草稿”两字的,质量普遍很低,亲们,就不要浪费时间在上面吧)
题目:
停车场管理
问题描述:停车场是一个能放n辆车的狭长通道,只有一个大门,汽车按到达的先后次序停放。若车场满了,车要停在门外的便道上等候,一旦有车走,则便道上第一辆车进入。当停车场中的车离开时,由于通道窄,在它后面的车要先退出,待它走后在依次进入。汽车离开时按停放时间收费。
基本功能要求:
(1) 建立三个数据结构分别是:停放队列、让路栈、等候队列。
(2) 输入数据模拟管理过程,数据(入或出,车号)。
因为觉得不是很难,做起来挺无聊的,就搞了个界面(字符显示,把屏分为了三个功能区,分别显示即时停车场的占用信息、车辆信息、以及命令输入窗口),能用类似Linux Shell的命令行方式来操作。
结果有点弄巧成拙了,有个很明显的BUG(应该是“find_car_out”函数的哪里错了,改了半天也没改出来),大家就不要细看了罢。
注意:本段程序只能在windows下运行。
parking_lot.h
#ifndef PARKING_LOT_H_INCLUDED
#define PARKING_LOT_H_INCLUDED
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <time.h>
#define park_lot_size 35
int RANDOM_SIZE=20;
inline void gotoxy(int y, int x)
{
COORD p;
p.X = x;
p.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), p);
}
void whereXY(int *x,int *y)
{
HANDLE h1;
CONSOLE_SCREEN_BUFFER_INFO scrInfo;
h1=GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(h1,&scrInfo);
*x=scrInfo.dwCursorPosition.X;
*y=scrInfo.dwCursorPosition.Y;
}
#endif // PARKING_LOT_H_INCLUDED
car.h
#ifndef CAR_H_INCLUDED
#define CAR_H_INCLUDED
typedef struct _car
{
char *license_plate;
time_t arrive_time;
time_t leave_time;
}st_car, *car;
typedef struct _car StackData;
typedef struct _car QueueData;
void car_print(car c);
car car_creat(int i);
#endif // CAR_H_INCLUDED
car.c
#include "car.h"
extern int RANDOM_SIZE;
char* car_license_plate_random(time_t t,int i)
{
char place[31][2] = {"京","津","沪","渝","冀"
,"豫","云","辽","黑","湘"
,"皖","鲁","苏","赣","浙"
,"粤","鄂","桂","甘","晋"
,"蒙","陕","吉","闽","贵"
,"青","藏","川","宁","新","琼"};
char *plate = (char*)malloc(sizeof(char) * 9);
while (plate == NULL)
{
plate = (char*)malloc(sizeof(char) * 9);
}
srand(t + i);
int random = rand();
plate[0] = place[random%31][0];
plate[1] = place[random%31][1];
plate[2] = random % 26 + 'A';
plate[3] = random % 10 + '0';
random /= 10;
plate[4] = random % 10 + '0';
random /= 10;
plate[5] = random % 10 + '0';
random /= 10;
plate[6] = random % 10 + '0';
random /= 10;
plate[7] = random % 10 + '0';
plate[8] = '\0';
return plate;
}
void car_print(car c)
{
struct tm *arrive;
struct tm *leave;
arrive = localtime(&c->arrive_time);
int hour = arrive->tm_hour;
int min = arrive->tm_min;
int sec = arrive->tm_sec;
leave = localtime(&c->leave_time);
// gotoxy(line,0);
printf("%s %02d:%02d:%02d %02d:%02d:%02d %2.2f"
, c->license_plate
// , arrive->tm_hour, arrive->tm_min, arrive->tm_sec
,hour,min,sec
, leave->tm_hour, leave->tm_min, leave->tm_sec
, (c->leave_time-c->arrive_time)*0.05);
return;
}
car car_creat(int i)
{
int tmp = i;
time_t t;
// struct tm *tm_t;
car pcar;
pcar = (car)malloc(sizeof(st_car));
while (pcar == NULL)
{
pcar = (car)malloc(sizeof(st_car));
}
time(&t);
// tm_t = localtime(&t);
srand((unsigned int)i);
while(tmp--)rand();
pcar->arrive_time = t;
pcar->leave_time = t + rand()%10 + 1;
pcar->license_plate = car_license_plate_random(t,i);
return pcar;
}
void printstar(StackData *x)
{
printf("*");
}
link_stack.h
#ifndef LINK_STACK_H_INCLUDED
#define LINK_STACK_H_INCLUDED
typedef struct st_StackNode StackNode;
typedef StackData *stackdata;
struct st_StackNode
{
stackdata data;
StackNode *next;
};
typedef struct _stack
{
StackNode *bottom;
StackNode *top;
}stack;
void stack_init(stack *s);
#define isempty(s) ((s)->bottom == (s)->top)
int push(stack *s, stackdata data);
int pop(stack *s, stackdata *data);
void stack_print(stack *s, void (*print)(StackData *),int line,int startnum);
void stack_star_print(stack *s);
void stack_star_print2(int length);
#endif // LINK_STACK_H_INCLUDED
link_stack.c
#include "link_stack.h"
void stack_init(stack *s)
{
s->bottom = (StackNode *)malloc(sizeof(StackNode));
// s->bottom->next = NULL;
s->top = s->bottom;
}
#define isempty(s) ((s)->bottom == (s)->top)
int push(stack *s, stackdata data)
{
StackNode *newnode = (StackNode *)malloc(sizeof(StackNode));
s->top->next = newnode;
newnode->data = data;
s->top = newnode;
return 0;
}
int pop(stack *s, stackdata *pdata)
{
StackNode *p = s->bottom;
if (isempty(s))
{
return -1;
}
*pdata = s->top->data;
while (p->next != s->top)
{
p = p->next;
}
s->top = p;
return 0;
}
void stack_print(stack *s, void (*print)(StackData *),int line,int startnum)
{
StackNode *p = s->bottom;
int no = 1;//车位号
int l = 0;//相对位移
if (isempty(s) == 1)
{
return;
}
p = p->next;
while(p != s->top)
{
if (no >= startnum && no < startnum + 13)
{
gotoxy(line + l++,3);
printf("%2d. ",no);
(*print)(p->data);
}
p = p->next;
no++;
}
if (p == s->top && no >= startnum && no < startnum + 13)
{
gotoxy(line + l,3);
printf("%2d. ",no);
(*print)(p->data);
}
while(l++<12)
{
gotoxy(line + l,2);
printf(" ");
}
// printf("%d", p->data);
}
void stack_star_print(stack *s)
{
StackNode *p = s->bottom;
gotoxy(5,2);
while (p->next != s->top)
{
printf("*");
p = p->next;
}
if (p->next == s->top)
{
printf("*");
}
}
void stack_star_print2(int length)
{
int i = length;
gotoxy(5,2);
printf(" ");
gotoxy(5,2);
while (i-->0)
{
printf("^");
}
printf("共%d辆",length);
}
link_queue.h
#ifndef LINK_QUEUE_H_INCLUDED
#define LINK_QUEUE_H_INCLUDED
typedef QueueData *queuedata;
typedef struct node {
queuedata data; //队列结点数据
struct node *link; //结点链指针
} QueueNode;
typedef struct {
QueueNode *rear;
QueueNode *front;
} LinkQueue, *linkqueue;
inline void InitQueue(linkqueue Q);
inline int QueueEmpty(linkqueue Q);
int GetFront(linkqueue Q, queuedata *x);
int EnQueue(linkqueue Q, queuedata x);
int DeQueue(linkqueue Q, queuedata *x);
void queue_star_print(linkqueue q);
#endif // LINK_QUEUE_H_INCLUDED
link_queue.c
inline void InitQueue(linkqueue Q)
{
Q->rear = NULL;
Q->front = NULL;
}
inline int QueueEmpty(linkqueue Q)
{
return Q->front == NULL;
}
int GetFront(linkqueue Q, queuedata *x)
{
if (QueueEmpty(Q)) return 0;
*x = Q->front->data;
return 1;
}
int EnQueue(linkqueue Q, queuedata x)
{
QueueNode *p = (QueueNode *)malloc(sizeof(QueueNode));
if (p == NULL)
{
return 0;
}
p->data = x;
p->link = NULL;
if ( Q->front == NULL )
{
//空,创建第一个结点
Q->front = Q->rear = p;
}
else
{
Q->rear->link = p;
Q->rear = p;
}
return 1;
}
int DeQueue(linkqueue Q, queuedata *x)
{
//删去队头结点,并返回队头元素的值
if (QueueEmpty(Q))
{
return 0; //判队空
}
QueueNode *p = Q->front;
*x = p->data; //保存队头的值
Q->front = Q->front->link; //新队头
if (Q->front == NULL)
{
Q->rear = NULL;
}
free (p);
// car_print(*x,3);
return 1;
}
void queue_star_print(linkqueue q)
{
QueueNode *p = q->front;
gotoxy(7,43);
if (p != NULL)
{
printf("*");
while (p->link != NULL)
{
printf("*");
p = p->link;
}
}
}
key.c
/*本段代码引用自http://blog.codingnow.com/2006/08/nbstdin.html*/
#include <windows.h>
#include <process.h>
#include <stdio.h>
#define BUFFER_MAX 1024
char g_nbstdin_buffer[2][BUFFER_MAX];
HANDLE g_input[2];
HANDLE g_process[2];
DWORD WINAPI console_input(LPVOID lpParameter)
{
for (;;)
{
int i;
for (i=0; i<2; i++)
{
fgets(g_nbstdin_buffer[i],BUFFER_MAX,stdin);
SetEvent(g_input[i]);
WaitForSingleObject(g_process[i],INFINITE);
}
}
return 0;
}
void create_nbstdin()
{
int i;
DWORD tid;
CreateThread(NULL,1024,&console_input,0,0,&tid);
for (i=0; i<2; i++)
{
g_input[i]=CreateEvent(NULL,FALSE,FALSE,NULL);
g_process[i]=CreateEvent(NULL,FALSE,FALSE,NULL);
g_nbstdin_buffer[i][0]='\0';
}
}
const char* nbstdin()
{
DWORD n=WaitForMultipleObjects(2,g_input,FALSE,0);
if (n==WAIT_OBJECT_0 || n==WAIT_OBJECT_0+1)
{
n=n-WAIT_OBJECT_0;
SetEvent(g_process[n]);
return g_nbstdin_buffer[n];
}
else
{
return 0;
}
}
parking_lot.c
#include "parking_lot.h"
#include "car.h"
#include "car.c"
#include "link_stack.h"
#include "link_stack.c"
#include "link_queue.h"
#include "link_queue.c"
#include "key.c"
void link_stack_test()
{
stack *s = (stack *)malloc(sizeof(stack));
stack_init(s);
stackdata data;
car c;
int i;
for (i = 0; i < 56; i++)
{
c = car_creat(i);
push(s, c);
}
// car car1 = car_creat(1);
// car car2 = car_creat(2);
// car car3 = car_creat(3);
// printf("push 1\n");
// push(s, car1);
// printf("push 2\n");
// push(s, car2);
// printf("push 3\n\n");
// push(s, car3);
printf("stack print:\n");
stack_print(s,car_print,1,1);
printf("\n\nstart poping\n");
pop(s, &data);
printf("1");
// printf("%p,\n",data);
car_print(data);
printf("2");
pop(s, &data);
car_print(data);
pop(s, &data);
car_print(data);
printf("\nstack print:\n");
// stack_print(s,car_print,8);
printf("[[[[[");
// stack_print(s,car_print,20);
stack_print(s,printstar,5,1);
printf("]]]]");
}
void link_queue_test()
{
linkqueue linkq = (linkqueue)malloc(sizeof(LinkQueue));;
queuedata qdata;
InitQueue(linkq);
car c;
int i;
for (i = 0; i < 3; i++)
{
c = car_creat(i);
EnQueue(linkq, c);
}
// printf("%s\n", QueueEmpty(linkq)==1 ? "queue is empty" : "queue is not empty");
//// EnQueue(linkq, car1);
// queue_star_print(linkq);
printf("数据已入队\n");
// car_print(c,2);
// printf("%s\n", QueueEmpty(linkq)==1 ? "queue is empty" : "queue is not empty");
// GetFront(linkq, &qdata);
// printf("%p",&qdata);
DeQueue(linkq, &qdata);
car_print(qdata);
// DeQueue(linkq, &qdata);
// car_print(&qdata,3);
// printf("%s\n", QueueEmpty(linkq)==1 ? "queue is empty" : "queue is not empty");
}
char *screen_init()
{
int i,j;
char *scr;
system("mode con cols=80 lines=27");
scr = (char *)malloc(sizeof(char) * 25 * 80 + 1); //" "// "
char *string[25] = //"-------------------------------------------------------------------------------- ",//0
{
"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓",//0
"┃ 停车场管理系统 ┃",//1
"┣━━━━━━━━━━━━━━━━━┳━━┳━━━━━━━━━━━━━━━━━┫",//2
"┃停车场↓ ┃出口┃ 让道↓┃",//3
"┣━━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━┫",//4
"┃ ┃",//5
"┣━━━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━┫",//6
"┃当前时间: ┃ ←门外便道┃",//7
"┣━━┯━━━━┯━━━━┯━━━━╇━━┳━━━━━━━━━━━━━━━━━┫",//8
"┃车位│ 车牌号 │到达时间│离开时间│收费┃ ┃",//9
"┠──┴────┴────┴────┴──┨┌───────────────┐┃",//10
"┃ ┃│ │┃",//11
"┃ ┃│ │┃",//12
"┃ ┃│ │┃",//13
"┃ ┃│ │┃",//14
"┃ ┃│ │┃",//15
"┃ ┃│ │┃",//16
"┃ ┃│ │┃",//17
"┃ ┃│ │┃",//18
"┃ ┃│ │┃",//19
"┃ ┃│ │┃",//20
"┃ ┃│ │┃",//21
"┃ ┃│ │┃",//22
"┃ ┃└───────────────┘┃",//23
"┗━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━┛"
};//24
for (i = 0; i < 25; i++)
{
// printf("[%d]",i);
// scr[i] = scr + 80 * i;
// scr[i] = (char *)malloc(sizeof(char) * 84);
// strcpy(scr[i],string[i]);
// printf("%s", scr[i]);
// strcpy(scr + 80 * i,string[i]);
for (j = 0; j < 80; j++)
{
*(scr + 80 * i + j) = *(string[i] + j);
}
}
*(scr + 80 * 25 ) = '\0';
return scr;
}
inline void reflash(char *scr)
{
gotoxy(0, 0);
puts(scr);
}
void help()
{
// ┃│ │┃
gotoxy(9,46);
printf(" 帮助目录 ");
gotoxy(11,46);
printf("exit:退出 help/?:帮助 ");
gotoxy(12,46);
printf("up:左屏上移 down:左屏下移 ");
gotoxy(13,46);
printf("clear:清屏");
gotoxy(14,46);
printf("键盘上下键可获得您打过的命令 ");
gotoxy(15,46);
printf(" ");
gotoxy(15,46);
printf(">");
}
int my_strcmp(char const *a, char const *b)
{
while(*a != '\0' && *a != 10)
{
if (*b == '\0')//a比b长
{
return 1;
}
if (*a++ != *b++)
{
return -2;
}
}
if (*b == '\0')
{
return 0;
}
else
{
return -1;
}
}
void find_car_out(stack *parking, stack *temp_park, StackNode *p,time_t time_now,int *num_park)
{
gotoxy(25,0);
// printf("123");
car c;
while (1)
{
if(p != parking->top)
{
//当前指针指向末尾结点之前
// car_print(p->data);printf("\n");
if (p->data->leave_time <= time_now)//找到匹配项,退出循环
{
break;
}
}
else//当前指针指向末尾结点,退出循环
{
break;
}
p = p->next;
printf("#");
}
gotoxy(25,0);
// printf("456");
// if (parking->top->data <= time_now)
// {
// pop(parking, &c);
// }
if (p == parking->top)
//在结尾之前没有匹配项了,处理结尾top
{
if (parking->top->data->leave_time <= time_now)
{
pop(parking, &c);
(*num_park)--;
free(c->license_plate);
free(c);
printf("&");
}
else
{
pop(parking, &c);
push(temp_park, c);
}
}
else
//找到结尾之前的匹配项
{
if (p->next != NULL)//
{
find_car_out(parking, temp_park, p->next, time_now,num_park);
}
while(parking->top != p)//将两个匹配项间的车辆移动到暂时停放处
{
//直到弹出停车场最里面的匹配车辆
pop(parking, &c);
push(temp_park, c);
}
pop(parking, &c);
(*num_park)--;
printf("$");
}
gotoxy(25,0);
// printf("789");
return ;
}
int main(void)
{
int i;
const char *line;
time_t time_pre;
time_t time_now;
time_t start_time;
struct tm *tm_t;
// time_t time_sec;
int x=11,y=46;
long long circle = 0;
long long circle_pre = 0;
long long circle_sec_num = 800000;
int Hz = 200;//动画变动的赫兹
float num_of_newcar_per_sec = 2;//默认平均每秒到达的车辆数 范围:(0,50)或更严格的(0,35)
//那么,每1/Hz秒,新车出现概率为num../Hz,即每Hz/num..个
//随机数出现一次,随机数范围可为(0,Hz/num..)
int num_park = 0;
int num_park_pre = 0;
// int num_mov = 0;
int num_wait_pre = 0;
int num_wait_now = 0;
int page_startnum = 1;
/*********************************************************************/
linkqueue waitqueue = (linkqueue)malloc(sizeof(LinkQueue));;
car newcar;
InitQueue(waitqueue);
stack *parking = (stack *)malloc(sizeof(stack));
stack_init(parking);
stack *temp_park = (stack *)malloc(sizeof(stack));
stack_init(temp_park);
// link_stack_test();
// link_queue_test();
printf("end");
//*
// system("cls");
// printf("\n");
car c;
char *scr = screen_init();
reflash(scr);
// getch();
//gotoxy(5,2);
//// 1234567890123456789012345678901234567890
//printf("***********************************");
time(&time_now);
time_pre = time_now;
start_time = time_now;
#define TIME_LIMITE 600
gotoxy(x,y);
printf(">");
create_nbstdin();
while(1)
{
circle++;
line=nbstdin();
if (line)//如果有回车
{
x = (x+2)%12+11;//下降一行
y = 46;//回到行首
// gotoxy(12,46);
// printf(">%s\n",line);
// gotoxy(13,46);
// printf("\n");
// printf("exit^%s = %d \n \n",line, my_strcmp(line,"exit"));
// printf("help^%s = %d \n \n",line, (my_strcmp(line,"help")));
// printf(" ?^%s = %d \n \n",line, (my_strcmp(line,"?")));
gotoxy(x,y);
printf(" ");
gotoxy(x,y);
printf(">");
if (my_strcmp(line,"exit") == 0)
{
printf(">break\n");
break;
}
else if ((my_strcmp(line,"help") == 0) || (my_strcmp(line,"?") == 0))
{
help();
}
else if (my_strcmp(line,"clear") == 0)
{
for (i = 11; i < 23; i++)
{
gotoxy(i,46);
printf(" ");
}
x = 11;
y = 46;
gotoxy(x,y);
printf(" ");
gotoxy(x,y);
printf(">");
}
else if(my_strcmp(line,"up") == 0)
{
page_startnum--;
if (!page_startnum)
{
page_startnum = 0;
}
whereXY(&y,&x);
stack_print(parking, car_print, 11,page_startnum);
// stack_star_print(parking);
stack_star_print2(num_park);
gotoxy(x,y);
}
else if(my_strcmp(line,"down") == 0)
{
page_startnum++;
if (page_startnum > num_park -12)
{
page_startnum = num_park -12;
}
whereXY(&y,&x);
stack_print(parking, car_print, 11,page_startnum);
// stack_star_print(parking);
stack_star_print2(num_park);
gotoxy(x,y);
}
else if(*line == 10)
{
;
}
else
{
printf("No such cmd!Please input");
whereXY(&y,&x);
x = (x+2)%12+11;//下降一行
y = 46;//回到行首
gotoxy(x,y);
printf("cmd 'help' or '?' for help.");
x = (x+2)%12+11;//下降一行
y = 46;//回到行首
gotoxy(x,y);
printf(" ");
gotoxy(x,y);
printf(">");
}
}
else
{
time(&time_now);
tm_t = localtime(&time_now);
/**每秒执行*/
if (time_now != time_pre)//
{
whereXY(&y, &x);
// printf("(%d,%d)",x,y);
gotoxy(7,12);
printf("%s",asctime(tm_t));
// printf("=%lld=%lld=%lld=%lld\n",circle,(long)(time_now-start_time),(circle/((long long)time_now-(long long)start_time)));
// strcpy(str, asctime(tm_t));
// printf("%s\n", str);
circle_sec_num = circle - circle_pre;
circle_pre = circle;
time_pre = time_now;
if (parking->bottom != parking->top)
{
find_car_out(parking, temp_park, parking->bottom, time_now, &num_park);
}
while (temp_park->bottom != temp_park->top)
{
pop(temp_park,&c);
push(parking,c);
}
if (num_wait_pre != num_wait_now)//如果有新车进入等待队列,刷新
{
num_wait_pre = num_wait_now;
queue_star_print(waitqueue);
for (i = num_wait_now; i < 35; i++)
{
printf(" ");
}
}
if (num_park_pre != num_park)//如果有新车进入停车场,刷新
{
num_park_pre = num_park;
stack_print(parking, car_print, 11,page_startnum);
// stack_star_print(parking);
stack_star_print2(num_park);
}
while (num_park < 35 && num_wait_now != 0)//停车场有空位且等待队列非空,将等待队列车辆放入停车场
{
// gotoxy(25,num_park*2);
// printf("%d",num_park);
DeQueue(waitqueue, &c);
push(parking, c);
num_park++;
num_wait_now--;
}
if (num_wait_pre != num_wait_now)//如果有新车进入停车场,刷新
{
num_wait_pre = num_wait_now;
queue_star_print(waitqueue);
for (i = num_wait_now; i < 35; i++)
{
printf(" ");
}
}
gotoxy(x,y);
}
// printf("*");
// Sleep(0);
}
if ((circle - circle_pre) % (circle_sec_num / Hz) == 0)//每到Hz分之一秒,执行
{
srand((unsigned int)circle);
// printf(".%d",(circle - circle_pre) / (circle_sec_num / Hz)>100);//检查每秒执行数是否正常
int tmp = (float)Hz / (float)num_of_newcar_per_sec;
if ((rand() % tmp) == 0 && num_wait_now <35)//是否有新车到达
{
newcar = car_creat((int)circle);
if (EnQueue(waitqueue, newcar) != 0)
{
num_wait_now++;
printf("p");
}
}
}
}
system("cls");
printf("系统退出!");
//*/
return 0;
}