用C++实现一个“不那么现实”的停车场管理系统。具体要求为:形状狭长且单侧入口的停车场只能容纳长度为N的车队。若停车场停满了,要求后来的车先停入便道,停车场中有车离开后再按顺序停入。
根据现实情况来模拟的话,停车场用STL stack来实现,便道用STL queue来实现。缴费记录用到.csv文件,具体用file I/O来实现。
以下代码和函数很多是基于C语言的。编程过程发现多个疑难点,在此给两点提醒:
1、理解并合理运用time.h的变量和函数。time_t类型的可变性和生命周期最开始会让人有点莫名其妙。以下代码没有涉及到的还有struct tm结构体,是用来提供更精确的时间信息的。
2、注意内存问题。比如操作char *类型的字符串时一定要清醒,特别是不熟悉C语言的同仁们(包括我,只是大一上学期C语言程序设计课集中学过)。譬如,可能你看上去一直在给字符串赋新值,但其实都是在一块相同的内存空间上做操作。此外,如果你不熟悉一些字符串操作函数的话,也可能出现一些意料之外的错误。
还有很多小细节,有些我也没有完全做好,文章先匆忙发出啦。
以下是完整代码,欢迎各位批评指正!(第一次发文章,赶上1024嘿嘿)
#include <queue>
#include <stack>
#include <time.h>
#include <math.h>
#include <cstdio> // in C #include <stdio.h>
#include <cstring> // in C #include <string.h>
#include <windows.h>
#define CPC 3 // CaPaCity of the parking lot
using namespace std;
struct car {
const char *_numPlate;
const char *_timeIn;
const int _begin;
};
void welcome(); // show the menu
void arrive(); // receive and handle the arrival of one car
bool carExist(const char *); // true if there're cars in the parking lot
void leave(); // handle the leavin of one car
void displayLot(); // display the condition of parking lot
void displayPave(); // display the condition of pave
void search(); // search for a car with number plate
void changePrice(); // change the price of parking fee
void displayBill(); // show the overall bill
void myWait(); // wait for response after each operation
void WriteInRecord(car, int); // write the bill in record
void del_line_break(char *); // deleting the '\n' of string
int price = 10;
char *numPlate;
stack<car> pLot;
queue<char *> pave;
int main() {
while (1) {
system("cls"); // "cls": clear screen
welcome();
int op;
scanf("%d", &op);
system("cls");
switch (op) {
case 1:
arrive();
break;
case 2:
leave();
break;
case 3:
displayLot();
break;
case 4:
displayPave();
break;
case 5:
search();
break;
case 6:
changePrice();
break;
case 7:
displayBill();
break;
case 0:
return 0;
default:
continue;
}
}
}
void welcome() {
printf ("\t**************************************************\n");
printf ("\t----------------欢迎来到我的停车场----------------\n");
printf ("\t-------------(模拟系统内8秒记1小时)-------------\n");
printf ("\t**************************************************\n");
printf ("\t* 1.车辆到达操作 *\n");
printf ("\t* 2.车辆离开操作 *\n");
printf ("\t* 3.显示停车场信息 *\n");
printf ("\t* 4.显示便道上情况 *\n");
printf ("\t* 5.查找汽车 *\n");
printf ("\t* 6.修改缴费标准 *\n");
printf ("\t* 7.显示停车收费明细表 *\n");
printf ("\t* 0.退出系统 *\n");
printf ("\t--------------------------------------------------\n");
printf ("\t* 收费标准:本停车场按照%d元/小时计费 *\n", price);
printf ("\t--------------------------------------------------\n");
printf ("\t-----输入数字(1/2/3/4/5/6/7/0)和回车来继续操作----\n");
}
void arrive() {
numPlate = new char[7];
printf("请输入即将停车的车牌号:");
scanf("%s", numPlate);
if (carExist(numPlate)) {
printf("\t停车场里已存在车牌号为%s的车\n", numPlate);
myWait();
return;
}
if (pLot.size() < CPC) {
time_t t1;
int t = time(&t1);
char *t2;
t2 = ctime(&t1);
del_line_break(t2);
printf("\t牌照为%s的汽车停入车位,当前时间:%s\n", numPlate, t2);
char *timeIn = new char[30];
strcpy(timeIn, t2);
pLot.push({numPlate, timeIn, t});
} else {
pave.push(numPlate);
printf("\t停车场位置不够,牌照为%s的汽车停入便道\n", numPlate);
}
myWait();
}
bool carExist(const char *numPlate) {
stack<car> tmp(pLot);
while (!tmp.empty() && strcmp(tmp.top()._numPlate, numPlate)) {
tmp.pop();
}
if (tmp.empty()) return false;
else return true;
}
void leave() {
char *num = new char[7];
time_t t1;
int t = time(&t1);
char *t2;
t2 = ctime(&t1);
del_line_break(t2);
printf("请输入即将离开的车牌号:");
scanf("%s", num);
bool flag = true;
stack<car> tmp;
while (!pLot.empty() && strcmp(pLot.top()._numPlate, num)) {
tmp.push(pLot.top());
pLot.pop();
}
if (!pLot.empty()) {
flag = false;
t = round((time(&t1) - pLot.top()._begin) / 8);
WriteInRecord(pLot.top(), t);
pLot.pop();
}
while (!tmp.empty()) {
pLot.push(tmp.top());
tmp.pop();
}
if (flag) {
printf("\t停车场不存在车牌号为%s的车\n", num);
myWait();
return;
}
printf("\t牌照为%s的汽车离开车位,当前时间:%s\n", num, t2);
printf("\t停车时长:%d小时,需付金额:%d元\n", t, price * t);
if (!pave.empty()) {
strcpy(num, pave.front());
pave.pop();
char *timeIn = new char[30];
strcpy(timeIn, t2);
pLot.push({num, timeIn, t});
printf("\t牌照为%s的汽车停入车位,停入时间:%s\n", num, t2);
}
myWait();
}
void displayLot() {
stack<car> tmp;
while (!pLot.empty()) {
tmp.push(pLot.top());
pLot.pop();
}
int cnt = 0;
printf ("\t*******************目前停车场状况***********************\n");
printf ("\t当前停车场共有%d辆车\n", tmp.size());
while (!tmp.empty()) {
printf("\t第%d辆车:%s,停入时间:%s\n", ++cnt,
tmp.top()._numPlate, tmp.top()._timeIn);
pLot.push(tmp.top());
tmp.pop();
}
myWait();
}
void displayPave() {
queue<char*> tmp(pave);
int cnt = 0;
printf ("\t*******************目前便道状况***********************\n");
printf ("\t当前便道共有%d辆车\n", tmp.size());
while (!tmp.empty()) {
printf("\t第%d辆车:%s\n", ++cnt, tmp.front());
tmp.pop();
}
myWait();
}
void search() {
char num[7];
printf("请输入要搜索的车牌号:\n");
scanf("%s", num);
int cnt = pLot.size();
stack<car> tmp;
while (!pLot.empty() && strcmp(num, pLot.top()._numPlate)) {
tmp.push(pLot.top());
pLot.pop();
cnt--;
}
bool inPlot = false;
if (!pLot.empty()) {
inPlot = true;
printf("\t车牌号为%s的车位于停车场第%d位\n", num, cnt);
}
while (!tmp.empty()) {
pLot.push(tmp.top());
tmp.pop();
}
if (inPlot) {
myWait();
return;
}
cnt = 0;
queue<char*> qTmp(pave);
while (!qTmp.empty() && strcmp(num, qTmp.front())) {
qTmp.pop();
cnt++;
}
if (!qTmp.empty())
printf("\t车牌号为%s的车位于便道第%d位\n", num, ++cnt);
else
printf("\t没有在停车场和便道发现车牌号为%s的车\n", num);
myWait();
}
void changePrice() {
printf("现在修改缴费标准,改为:\n");
scanf("%d", &price);
printf("\t缴费标准已修改\n");
myWait();
}
void displayBill() {
FILE *fp = fopen("record.csv", "r");
if (fp == NULL) {
fprintf(stderr, "fopen() failed.\n");
exit(EXIT_FAILURE);
}
char row[80];
char *token;
printf ("\t**************************************************\n");
printf("\t车牌号\t\t停入时间\t 该次时长 收费\n");
printf ("\t**************************************************\n");
while (fgets(row, 80, fp) != NULL) {
// printf("\t%s", row);
token = strtok(row, ",");
while (token != NULL) {
printf("\t%s", token);
token = strtok(NULL, ",");
}
}
fclose(fp);
myWait();
}
void myWait() {
getchar();
printf ("\t*************请按下回车键返回主界面****************\n");
getchar();
}
void WriteInRecord(car c, int time) {
FILE *fp = fopen("record.csv", "a");
if (fp == NULL) {
fprintf(stderr, "fopen() failed.\n");
exit(EXIT_FAILURE);
}
fprintf(fp, "%s,%s,%d,%d\n", c._numPlate, c._timeIn, time, price * time);
fclose(fp);
}
void del_line_break(char *time) {
for (int i = 0; i < 30; i++) {
if (time[i] == '\n') {
time[i] = '\0';
break;
}
}
}
还有一点小心得: 就是自己写代码的时候可以多借助注释来理清思路,脑子再好也可以有笔记来助力。