程序设计 - 停车场管理系统

更新时间:2023-03-11 05:13:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

程序设计报告

( 2014 / 2015 学年 第 1学期)

题 目:停车场管理系统

专 业 组长 学号姓名 组员 学号姓名 指 导 教 师 指 导 单 位 日 期

分工成员组长() 代码部分:取车、查询信息、修改停车费费率模块 实验报告:测试数据和结果分析、调试过程中的问 题 -

组员() 组员() 评分项 遵守机房规章制度 上机时的表现 学习态度 程序准备情况 程序设计能力 代码部分:管理员登陆模块 实验报告:概要设计和课程小结 代码部分:停车模块的实现 实验报告:课程内容和要求、需求分析 优秀 良好 中等 差 评分细则 团队合作精神 课题功能实现情况 算法设计合理性 用户界面设计 报告书写认真程度 内容详实程度 文字表达熟练程度 回答问题准确度 简短评语 教师签名: 年 月 日 级评分等备注 评分等级共五种:优秀、良好、中等、及格、不及格 停车场管理系统

一、 课题内容和要求

-

停车场管理是一个计时收费系统,同时也是一个能对车位进行管理的系统,最基本的功能是实现停车、取车、查询以及修改停车费费率等功能。同时,为了使用的方便和安全的考虑设计了管理员能对密码进行修改的功能。在停车的功能中采用了文件流的形式,对车位、车牌号、车型都进行了保存,以便于查询功能的实现,除此之外,也是为了能够实现在取车模块中利用输入的车牌号自动计算出停车的费用。停车位第一个为空的位置,由程序查询自动给出车位号,如果车位已满要给出提示。 取车时,需要根据车辆停泊时间自动计算费用(半小时内以半价计算,超出半小时不足一小时按一小时计算)并显示在屏幕上,可以随时根据车牌查询是否入库。可以随时根据车位查询该位置上的相关信息。本系统对不同车型的费率给出了默认值,管理员可以根据实际需要对费率进行修改。

功能要求:用C/C++设计一个程序实现停车场管理系统,要求如下: (1) 管理人员根据口令进入系统;

(2) 管理人员有权限对登陆账号和密码进行修改;

(3) 管理车位信息(车位编号,状态)和每小时的收费费率;

(4) 停车时录入汽车停泊信息(车牌号,车型,停泊位置,停泊开始时间);如果车位已满要给出提示;

(5) 取车时,根据车牌取,如果没有给出提示;需要根据车辆停泊时间自动计算费用并显示在屏幕上。

(6) 管理人员可以根据需要随时更改每小时的收费费率。

二、 需求分析

停车场管理系统的功能框架图如图1所示。

-

图1 功能框架图

(1)系统主要包括了管理员登陆、停车操作、取车操作、信息查询、费率修改这五大模块,每个模块都用用相应的函数来实现这些功能。

(2)在管理员登陆模块中,设置了三次输入机会,用户名和密码事先用文档存储,供使用者进入系统;若管理员连续输入密码错误超过提示,则系统给出修改密码或者退出系统的提示,这些功能在函数名为loadin()的函数中实现。

(3)管理员登陆模块结束之后便到了系统的主要界面,选择操作1是停车模块。在选择停车操作之后,系统能够实现“将第一个为空的位置,由程序查询自动给出车位号,如果车位已满要给出提示”这一功能用函数compare()和jugement()共同实现的。进入停车模块后,还应选择不同的车型进行停车,这一过程会调用putcar()和gettime()函数,用来给出不同车型的费率和调用停车时的系统时间。

(4)通常选择了停车操作之后取车和查询功能才会有意义,所以取车和查询公共主要是使用了campare()函数,调用strcmp()字符串比较函数对输入的车牌号和停车时的车牌号进行比较,若相同,则返回该车位,达到取车和查询的作用。

(5)不同的停车场可以根据需要修改每种车型的车辆对应的费率。这个功能在修改费率的模块中实现。

(6)根据不同的车型以及其停泊时间收费,间差乘以单价就是最后收费,其中取车时,需要根据车辆停泊时间自动计算费用(半小时内以半价计算,超出半小时不足一小时按一小时计算)并显示在屏幕上。这个功能需要调用系统时间,因此在整个程序中包含了头文

-

件后(#include)利用结构这种数据类型来实现。

三、概要设计

1. 主要结构体

为了实现停车场管理系统的停车、取车、查询、修改功能,主要用一个while循环,通过输入的数字选择相应的操作。同时为了实现每个模块的功能,引用一些相应的子函数。 下面是主要结构体的流程图:

图2 主要结构体流程图

2. 主要函数流程图

(1)管理员登陆模块

管理员登陆模块是用函数loadin()来实现的,在loadin()函数中对账号和密码都

-

有三次的输入机会,用变量ai来记录输入的次数,当ai>=3时,进入修改密码的界面。在修改密码模块了,用strcpy()函数将输入的字符串adpassword1赋值给密码adpassword(adpassword为全局变量,所以才能起到修改的作用)。修改完成密码后,在loadin()函数中再次调用loadin()函数,这样在修改密码后就能重新回到登陆界面进行登陆,大体程序流程图如下:

图3 管理员登陆模块流程图

(2)比较函数compare()

在停车场管理系统的取车、查询模块中都需要用到输入“车牌号判断停车场中是否有该车”这个功能,而compare()函数就是用来实现这个功能的。其大概思路是,通过输入的字符串与系统储存有的字符串进行比较,如果字符串相等就返回一个0,如果不相等就返回非0,而通过0和非0的控制,便能实现判断的功能,其流程图如下所示:

-

图4 字符串比较函数流程图

(3)搜索空车位函数jugement()

对于停车操作来说,需要在所有停车位中找到第一个空车位,并返回这个车位。在该系统中,这个功能由函数jugement()来实现。设int型变量j为车位编号,利用数字position[j]的值是否为1,来判断是车位是否为空(这里是将1视为有车,0为无车)。

图5 搜索空车位函数流程图

在这个函数中还要注意:在用while循环对每个车位进行逐个判断的时候,j一定要

小于停车场的总车位。除此之外,返回第一个空车位表示将要在这个车位进行停车,因此要重新将position[j]的值置为1。

-

四、源程序代码

#include #include #include #include using namespace std; class car {

public:

char no[10]; int pos; double fee; void putcar(); void takecar(); void changefee(); };

class Time {

public: int hour; int min;

void getime(); };

char adpassword[10]=\char adname[10]=\int i,poi;

int position[50]={0};//全局变量 car carin[50]; Time catime[50];

double Fee1=6.0, Fee2=5.0, Fee3=4.0 , Fee4=3.0 ; int jugement(); int compare(); void search_no(); void search_position(); void loadin(); void main(){

//---------------------------------------------管理员登陆模块----------------------------

loadin();

//--------------------------------------------------登陆模块结束---------------------

int k=0;

-

cout<<\ cout<<\请选择:\

<<\ <<\●1.停车操作 \ <<\●2.取车操作 \ <<\●3.查询信息 \ <<\●4.修改车费\ <<\●5.退 出\

<<\

ofstream outfile(\车辆信息.txt\if(! outfile)

{cerr<<\exit(1); }

while(cin>>k) {

if(k==1) {

i=jugement();//--------------通过jugement()函数返回第一个空的车位i cout<<\ cout<<\请输入车牌号:\

cin>>carin[i].no; //用户输入停在第i个车位的车牌号 carin[i].putcar();

cout<<\请选择:\

<<\

<<\●1.停车操作 \ <<\●2.取车操作 \ <<\●3.查询信息 \ <<\●4.修改车费 \

<<\●5.退 出\ <<\

string time1; time_t t; time(&t);

time1=ctime(&t);

cout<

outfile<

-

}

if(k==2) {

poi=compare(); carin[poi].takecar();

cout<<\请选择:\

<<\

<<\●1.停车操作 \ <<\●2.取车操作 \ <<\●3.查询信息 \ <<\●4.修改车费 \

<<\●5.退 出\ <<\

continue; }

if(k==3) {

int x; while(1) {

cout<<\请输入数字选择需要的操作:\ cout<<\

cout<<\ <<\●1.查询车牌号\ <<\●2.查询车位\ <<\●3.退出查询\

<<\ cin>>x; if(x==1) { search_no(); break; }

else if(x==2) {

search_position(); break; }

else if(x==3) {

-

break; }

else

cout<<\选择错误,请重新选择:\ }

cout<<\请选择:\

<<\

<<\●1.停车操作 \ <<\●2.取车操作 \ <<\●3.查询信息 \ <<\●4.修改车费 \

<<\●5.退 出\ <<\ }

//outfile.close(); if(k==4){

carin[i].changefee(); continue; } if(k==5){ exit(0); } } }

//-----------------------------------------------loadin()----------------------------------- void loadin(){

char an[10],ap[10]; int ai=0;

cout<<\ -------------欢迎使用XX停车场管理系统-------------\ while(1) {

cout<<\

cout<<\请输入管理员用户名:\ cin>>an;

-

if(strcmp(adname,an)) {

cout<<\此用户名不存在!\\n\ ai++; if(ai==3) exit(0);

continue; } else {

cout<<\请输入密码:\ cin>>ap;

if(!strcmp(adpassword,ap)){ break;} else {

cout<<\密码错误!\\n\ ai++; if(ai==3){ cout<<\ cout<<\密码连续输入错误3次,请重新选择操作:\ cout<<\ cout<<\●1.修改密码\ cout<<\●2.退出系统\ cout<<\ int k; while(cin>>k){ if(k==1){ cout<<\请输入新的密码,密码不超过10位数:\ char adpassword1[10]; cin>>adpassword1; strcpy(adpassword,adpassword1); cout<<\你的新密码是:\ cout<

-

}

continue; } }

cout<<\登陆成功!\} }

//-------------------------------------------------------------- jugement() -------------------- int jugement() //-------------------------判断出第一个空的车位 {

int j=0;

while(position[j]==1&&j<50) { j++; }

cout<<\共有50个停车位,当前可使用停车位 :\cout<<\

cout<<\本停车场收费标准如下:\cout<<\

cout<<\ 货车每小时\元,客车每小时\元,轿车每小时\元,其它车辆每小时\元。\

cout<<\ 注:停车时间小于30分钟的按0.5个小时计算,超过30分钟但不足1小时的按1个小时收费\if(j<50)

position[j]=1; //当找到第一个空车位时(即position=0时,并且满足车位号j<100的情况下) ,然后选择该车位停车,

//停车后将position重新置为1,表示该车位现在已经停车了。(在这种情况下表示找到空车位后就必须停在这个车位上) return j; }

//-------------------------------------------------compare()---------------------------- int compare() {

char ch[10];

cout<<\请输入车牌号:\ cin>>ch;

for(int k=0;k<50;k++) {

if(!strcmp(ch,carin[k].no)) // ---------------------将输入的车牌号与停车场上的每个位子的车

-

辆进行比较(包括那些没停车的车位) {

if(position[carin[k].pos-1]==1) // 在car::putcar()函数中因为要输出车位号,所以将对象数组carin[k].pos变为了carin[k].pos+1,

// 于是用数组position[]找已经停车的车位时要将其处理为carin[k].pos-1 {

return (carin[k].pos-1); break; } } }

if(k=50) return k; }

//------------------------------------------- car::putcar()--------------------------------- void car::putcar() {

int t; //车辆类型的变量

while(1) {

cout<<\请选择车型:\cout<<\

cout<<\ <<\■货车请输入1\ <<\■客车请输入2\ <<\■轿车请输入3\ <<\■其他车辆请输入4\

<<\cin>>t; if(t==1) {

carin[i].fee=Fee1;break; }

else if(t==2) {

carin[i].fee=Fee2;break; }

else if(t==3) {

carin[i].fee=Fee3;break; }

else if(t==4)

-

{

carin[i].fee=Fee4;break; }

cout<<\输入错误!请重新输入:\\n\ }

if(i==50)

cout<<\对不起,车位已满!\\n\

carin[i].pos=i+1; //-------------------自动输出车位号,数组里0表示第一位,而车位的第一位是1,所以carin[i].pos=i+1;

cout<<\

cout<<\已成功选择车位!车位号是:\ catime[i].getime();

cout<<\现在时间是:\ cout<<\ }

//------------------------------------------------- car::takecar()---------------- void car::takecar() {

int hour1,min1; double charge; if(poi<50) {

position[poi]=0; //-------------------通过取车操作后,重新将该车位设定为空车位 hour1=catime[poi].hour; min1=catime[poi].min; catime[poi].getime();

hour1=catime[poi].hour-hour1; min1=catime[poi].min-min1;

if(min1<30)//计算出停车时间,不足30分钟的按30分钟计算 charge=carin[poi].fee*hour1+carin[poi].fee*0.5; else

charge=carin[poi].fee*hour1+carin[poi].fee;

cout<<\车费为:\元.\\n\ //计算出车费输出 } else

cout<<\无此车!\\n\ }

-

//---------------------------------------- Time::getime()----------------------- void Time::getime() {

struct tm *newtime;

time_t long_time; //time_t用来定义长整型数 long_time

time( &long_time );

newtime = localtime( &long_time ); hour=newtime->tm_hour; min=newtime->tm_min; }

//-------------------------------- search_no()----------------------------- void search_no() {

int poi=compare(); if(poi<50)

cout<<\此车已入库,车位为:\ else

cout<<\此车没有入库。\\n\ //根据车牌号查询是否入库 }

//------------------------------------------- search_positon()---------------------- void search_position() { int loc;

cout<<\

cout<<\车位号是:\根据车位查询车位状态 cin>>loc;

if(position[loc-1]==1) {

cout<<\车牌号:\

cout<<\停车时间:\停车直到现在的时间 } else

cout<<\此车位无车!\ }

//-------------------------------

void car::changefee(){ cout<<\请选择修改的车型:\

-

cout<<\

<<\ ■修改 货车费用 请输入1 \ <<\ ■修改 客车费用 请输入2 \ <<\ ■修改 轿车费用 请输入3 \ <<\ ■修改 其他费用 请输入4 \ <<\ ■退 出 修 改 请输入5 \ <<\ int type; cin>>type;

while(1){ if(type==1){ double fee1; cout<<\每小时货车费用:\ cin>>fee1; Fee1=fee1; cout<<\车费修改成功!\ break; } else if(type==2){ double fee2;

cout<<\每小时客车费用:\ cin>>fee2; Fee2=fee2; cout<<\车费修改成功!\ break; }

else if(type==3){ double fee3;

cout<<\每小时轿车费用:\ cin>>fee3; Fee3=fee3;

cout<<\车费修改成功!\ break; }

else if(type==4){ double fee4;

cout<<\每小时轿车费用:\ cin>>fee4; Fee4=fee4;

cout<<\车费修改成功!\ break; }

-

else if(type==5){ break; } }

cout<<\请选择:\

<<\

<<\●1.停车操作 \ <<\●2.取车操作 \ <<\●3.查询信息 \ <<\●4.修改车费 \

<<\●5.退 出\ <<\ }

//----------------------------------------------------程序结束---------------------------。

五、测试数据及其结果分析

(1)修改密码时密码长度超过限制引起的错误

图6 修改密码时密码长度超过限制的错误登陆界面

因为修改密码的时候字符串长度设置为10个字符,当密码长度超过10位就会引起内部错误(字符‘wcx’为正确的登陆账号)。如果设置一个密码的字符长度判断功能的函数,能让输入超过十位后重新输入,就可以解决这个问题。 (2)账号输入错误引起的不能正常退出

-

图7 账号输入错误引起的不能正常退出的界面图

账号连续输入错误后却进入了系统,之所以出现这个原因是因为在判断账号的错误

次数的循环中没有正常退出,代码如下:

if(strcmp(adname,an)) { cout<<\此用户名不存在!\\n\ ai++; if(ai==3)

return; // 在这里只要把return改为exit(0)后就能得到正确结果 continue;}

修改得到的正确结果如下图所示:

-

图8 账号输入错误正常退出系统的界面图

(3)选择停车操作后显示的停车费率

图9 修改停车费率前信息显示图

刚进入系统是若没有选择修改车费的操作,此时显示的费率则是系统默认的,这是由于程序里将代表四种车型的费率的变量Fee1、Fee2、Fee3、Fee4的设为了全局并且赋了初值。修改了车费费率的图如下:

图10 修改停车费率后信息显示图

不足的是必须是选择了停车操作之后车位的信息和费率才能显示出来,实用性差了一些。

六、调试过程中的问题

(1).字符串比较函数strcmp()的使用

在C/C++语言中,常用strcmp()函数来比较两个字符串,一般形式为strcmp(字 符串S1,字符串S2)。当S1=S2时,返回值为0,否则为非零。在管理员用户登录 模块处理输入的账号和密码时就使用了该功能:

if(strcmp(adname,an)) // an为用户输入的账号 {

cout<<\此用户名不存在!\\n\ }

-

这里在设计的时候比较容易出错,因为若两个字符串不相等,则strcmp()返回 的值是非零,在if条件下为真,所以才会输出用户名不存在,在看程序的时候很 容易会看成是两个字符串相等后输出用户名不存在。

在运用string类提供的strcmp(s1,s2)的函数时还需要参数s1和s2的类型,

若s1和s2的类型都char的时候,则编译器不会报错,若s1和s2的类型都为 string的时候编译器便会提示类型错误,这时候应修改为 strcmp(s1.c_strc ,s2.c_strc); 这样才能对strcmp()函数的正确使用。

(2)continue和break的使用

在while和for的循环中,continue和break是非常常见的用来控制循环的语

句,continue和break的使用不相同而且还很容易出错。有一种最常见的错误 便是非法使用,比如在一些非while、for、if 这些循环或者判断的语句下使用, 编译器在编译的时候就会给出“illegal break”或者“illegal continue”这 样的报错,这是比较容易修改的错误的;还有一种是比较难发现的错误,就是 在很多循环嵌套的时候经常会发现不知道程序跳到哪一步了。比如在“管理员 登陆”模块的时候就出现过修改密码后一直停在输入账号和密码这个这里,在 loadin()的后面加入break语句后就能解决问题了。而这就需要用visual C++ 自带的调试器进行调试,去发现错误。

调试的一般思路是在你觉得最有可能出错的地方,或者你不确定循环是不是跳 到的地方按F9设置断言,然后按F5进行局部调试,等到程序运行到断言的位 置后再一步一步按F10进行判断,就能发现哪里出错了,这是比较可靠地判断 出错误的方法。

(3)Car类设计的作用

在停车场管理系统中,多次调用了同一辆车的车牌号、停车费用、车位,因此 为了编程的方便,将车牌号、费用和车位这些变量设为类car的公有成员。同时

-

还申明了car类的对象数组carin[]为全局变量,数组的大小表示停车位的多少, 每个停车位用全局变量i来表示。这样做的好处是使函数书写方便,比如说,当 要用到第i个车位的车牌号,只要用carin[i].no就可以很简洁的很方便的实现。

(4)停车费费率修改模块的实现

对于不同的停车场来说,车费的费率是要可以修改的,为了实现这个功能,在类 car中设置了changfee()公有函数成员。同时用了4个变量Fee1、Fee2、Fee3、 Fee4分别代表货车、客车、轿车、其它车辆的费率。然后将修改过的Fee1、Fee2、 Fee3、Fee4分别赋值给carin[i].fee,就可以实现修改停车费费率的修改。

在程序设计的时候,需要注意一些细节的处理:Fee1、Fee2、Fee3、Fee4这 四个变量必须设置成全局变量,然后给一个初始值。如果不修改就按初值来计算。 如果这四个变量放在putcar()的函数下,则无法修改成功。

(5)获取系统时间

在停车场管理系统中,对车费费率的计算需要运用的系统时间,即把费率乘上 停车的时间就可以得出停车的费用。因此在停车的时候就必须读取当前的时间, 在取车的时候再读取一次系统时间,两次相减就能得到停留的时间。

其中,time()函数获取到的并不是我们常表示的时间,所以要用localtime 函数来将它转化为本地时间。日期和时间的函数都包含在time.h函数中,因此 头文件中必须包括。初此之外,time()函数返回的值不是常见的类型,而是 time_t。

七、课程设计总结

经过大一第一学期对C++这一课程的学习,我学了基本的理论知识,建立了基本的C++程序设计的思想,为此次程序设计实验打下了基础。

为期两周的上机实验,让我们了解到自己知识体系的不足之处,让我们知道知识不能仅仅局限于课本以及理论体系,要用实践来证明和巩固。通过程序设计,进一步的巩固了用C++语言编写程序的能力,并且利于更好的掌握C++语言!这次实验无疑是一次非常好

-

的加强自己C++语言编写程序能力的机会,我们都非常珍惜。

虽然看起来两周的时间很充裕,但是我们已经有半年多时间没有学习过C++,其中的大部分知识都已经记不清,而且这个程序设计还涉及到一些我们没有学过的知识点,在编写代码时需要查阅书本,上网查找资料也是必不可少的。所以编写代码的时间对于我们来说还是比较紧的,过程也比较艰辛,还请教了不少学霸。所以我建议老师在给我们布置题目的同时要给我们一些对于题目的指点,让我们不至于那么迷茫,并且解决我们在过程中遇到的困难。虽然实验周是两周,但真正在机房的时间很少,很多同学自己在课下没人督促不会主动去编写代码,所以我建议增加上机时间,同学们也有更多的时间和耐心去解决自己的问题。在机房时,有很多同学会趁着老师不在时看视频玩游戏,希望老师加强管理,让同学们真正从实验中获得知识。

这次的编程实验是对更深层次知识的考验,不再是以前的小儿科,看起来比较简单的题目要求实现起来却十分困难,不仅考验了同学们对知识的掌握程度,也考验了同学们是否耐心和细心。即使是一点小错误也有可能使系统无法运行,在编写代码时可谓是细心细心再细心。以前学C++时实现的都是比较简单的代码,并且只是对知识把握的考察,并不实用。这次的编程实验是真正用于生活,让我们知道C++语言的实用性,增加对它的兴趣,巩固自己的知识体系。

总之这次的编程实践让我们受益匪浅,希望以后的编程实践会越来越好。

-

本文来源:https://www.bwwdw.com/article/83ow.html

Top