汽车站车票管理系统(C++版)

设计要求

  1. 程序菜单功能

一个汽车站每天有n班通往各地的车,每班车都有唯一的车次号(00100,00101,00102,…),发车时间,固定的路线(起始站、终点站),大致的行车时间,固定的额定载客量等信息。每班车信息如下:

表1.汽车站汽车数据库列表

车次                    

发车时间

起点站

终点站

行车时间

票价

额定载量

已售票数

00101

6:00

南京

盐城

3.5

30

45

00102

7:30

南京

连云港

4

40

40

00103

8:00

南京

宿迁

6

55

40

要求设计一个车票管理系统,分别供管理员和顾客使用。进入主窗口后,选择1进入管理员窗口;选择2进入普通顾客窗口;选择3退出系统。主窗口及不同用户的窗口如表2所示。

表2.不同窗口内容

主窗口

管理员窗口

普通顾客窗口

  1. 管理员登录
  2. 普通顾客登录
  3. 退出

请输入选择:

  1. 增加车次信息
  2. 查看所有车次信息
  3. 车辆信息查询
  4. 注销车次
  5. 退出

请输入选择:

  1. 车辆信息查询
  2. 购买车票
  3. 退票
  4. 退出

请输入选择:

1.管理员账户

(1)身份验证:要求通过用户名密码验证才能使用管理员账户(默认用户名为admin,密码为123)。注意:输入密码时要进行密码保护操作,即将输入的字母变成*号。如果用户密码错误,将会反复要求重新输入;

(2)当通过身份验证后,系统自动装载配置文件(即存放该汽车站汽车数据的文件)里的内容至数组timetables中,并进入管理员菜窗口(如表2第二列);在执行本功能前,请准备好配置文件,文件名请自行给出(如bus.txt)。文件格式如下(每行是一班车的信息,分别对应着车次号,发车时间(小时),发车时间(分钟),始发站,终点站,大约时长,票价,最大载客量,已售票数):

表3.配置文件内部基本信息(例)

00103  14 30 南京   北京   10 80 45   0

00104  15 10 南京   长沙   10 50 50   0

00105  17 20 南京   武汉   10 100 40   0

00106  10 20 南京   宿迁   4  40 40   0

(3)增加车次信息:增加车次时必须给定车次,发车时间(包括小时和分钟),起点,终点,行车时间,固定的额定载客量和票价。增加车次后要将信息写入配置文件中(如bus.txt)。注意:必须确保输入的车次号必须不重复,且如果当天的日志文件已生成,则增加的车次第二天生效。

(4)查看所有的车次信息:按行显示该汽车站所有车次的信息(包括车次,发车时间,起点,终点,行车时间,固定的额定载客量)。

(5)车辆信息查询:能够根据车次号和终点站分别进行查询,若车次或终点站不存在,则应该给出提示;如果存在,则显示该车辆信息。注意:如果按终点站查询,则要求显示所有的查询结果,且结果按发车时间升序排序。

(6)注销车次:输入要删除车次的车次号,首先查询该车辆是否存在,若该车不存在,则给出提示信息;如果存在则相应显示该车信息,并询问是否删除,如果是则删除该车次,并将信息写入配置文件中(如bus.txt); 注意:如果当天的日志文件已经生成,则注销车次第二天生效。

(7)退出:退出管理员账户,并将信息重新写入配置文件中(如bus.txt)。

2.顾客账户

(1)信息导入:整个汽车站的车次基本信息存放于配置文件bus.txt中。每天第一次使用顾客身份登录时,系统会从bus.txt中读取数据到数组timetables中(注意每辆车的已售票数的初始值为0),并将数组timetables的信息写入到一自动生成的日志文件(以当天日期命名,如2019-9-15.log)中。如果顾客身份不是第一次登录,则数据从当天的日志文件中读取数据到数组timetables中。

(2)车辆信息查询:能够根据车次号和终点站分别进行查询,若车次或终点站不存在,则应该给出提示;如果存在,则显示该车辆信息。注意:如果按终点站查询,则要求显示所有的查询结果,且结果按发车时间升序排序,且必须显示每辆车是否已停止服务。

(3)购买车票:输入要购买的车次,如果该车次不存在,给出提示。如果该车次存在则输出该车次的信息。注意:只有系统时间距发车时间大于十分钟时方可购票。如果小于10分钟则不可买票,否则输入购买的车票数目,并判断剩余的票是否大于等于要购买的票数,如果是则可以买票,同时更改已售车票数,并将相应信息写入当天的日志文件中;否则提示车票数不够。

(4)退票:输入要退票的车次,如果该车次不存在,给出提示;如果该车次存在则输出该车次的信息。注意:只有系统时间距发车时间大于十分钟时方可退票。如果小于10分钟则不可退票,否则输入退票数目,并判断售出的票是否大于等于要退的票数,如果是则可以退票,同时更改已售车票数,并将相应信息写入当天的日志文件中;否则提示用户输入错误。

(5)退出:退出顾客账户,将相应信息写入当天的日志文件中。

  1. 数据结构说明

1. 定义一个结构体数据结构用于存放每个车次的信息

struct Timetable    //车辆信息结构

{  char no;//班次

   int hour;//发车时间,小时

   int minute;//发车时间,分钟

   char Starting_station[10];//始发站

   char Last_station[10];//终点站

   float time;//行车时长

   int fare; //票价

   int max_number;//最大载客量

   int sold_number;//已售票数

}

2. 该汽车站汽车班次信息用数组来存储,如果不考虑动态数组空间的话,开始可将数组长度设置得大一些。

3 数据文件

数据文件中的信息是可以永久保存的,而内存中的信息当程序结束后就不存在了。本课设用配置文件(如bus.txt)及日志文件(以每天日期做文件名,如2019-9-15.log)模拟实现“数据库(即数据文件)”,数据库中存储的是该汽车站汽车班次信息,可永久保存。当以管理员身份程序运行时,所有的汽车班次信息从bus.txt文件中搬入内存,即存储在内存中的timetables数组中;当以普通顾客身份运行程序时,汽车班次信息从当天的日志文件文件中搬入内存。程序结束运行时,所有的汽车班次信息均由内存搬到(存储到)相应的数据文件中(管理员身份写入到bus.txt,普通顾客写入到当天的日志文件中),下次运行时再次调入到内存中。

注意:文件对使用系统的用户来说是“看不见的”,是系统内部处理用到的。当管理员用户验证通过后或普通用户登录后将自动调用ReadFromFile()函数将相应文件内容加载到timetables数组中。当对timetables中的数据进行修改后,相应地调用WritetoFile ()函数将内存timetables数组的内容写入对应文件(管理员写入bus.txt中,普通顾客写入到当天日志文件中)。

  1. 课程设计实现说明

1.定义主函数,在主函数中定义一个Timetable型的数组timetables用于存放该汽车站所有车次信息。所有的操作都是针对该数组执行的。

2.本项目涉及二级菜单,请仿照上述菜单设计进行拓展,给出本题的菜单实现。在菜单设计时将菜单设计练习中的“cout<<" Function1"<<endl;”等替换成调用每一个菜单功能的实现函数。

3.主函数和对应于每个菜单功能的实现函数参见“四、部分函数代码提示”。

  1. 部分函数代码提示

1. 主函数以及各级菜单函数的定义:

int main()

{  int UserChoice;

   Timetable timetables[100]; 

   while(1)

   {   switch(UserChoice = MainWindowSelect())

       {

       case 1:  AdminMode(timetables,"bus.txt");break;  //管理员模式

       case 2:  PassagerMode(timetables,"bus.txt");break;   //顾客模式 

       case 3:  if (Quit()!=1)continue;                    //退出

       }  

       if (UserChoice==3) break;

   }

   return 0;

}

void AdminMode(Timetable *timetables,char *filename) 

{   Signin();

    int n=ReadFromFile(timetables,0,"bus.txt");

    while(1)

    {   int AdminChoice = AdminWindowSelect();

        switch(AdminChoice)

        {

        case 1: n = AddBus(timetables,n) ;WritetoFile(timetables,n,filename);

system("pause");break;      //增加车次信息,并及时写到文件中

        case 2: ShowTimetable(timetables, n);system("pause");break;   //浏览时刻表

        case 3:    Query(timetables,n);system("pause");break;    //车辆信息查询              case 4: n = DelBus(timetables, n);system("pause");

WritetoFile(timetables,n,filename); break;//注销车次,并及时写到文件中

        case 5:    WritetoFile(timetables,n,filename);    

            return ;//返回上级菜单,并将信息保存回bus.txt文件

        }      

    }

}

void PassagerMode(Timetable *timetables,char *filename)

{   char LogFileName[200];   

    GenerateLogFileName(LogFileName);//根据当前日期生成日志名

    int n = InitializaionPassagerMode(timetables,LogFileName,filename);   

    int PassagerChoice;

    while(1)

    {   switch(PassagerChoice= PassagerWindowSelect())

        {

        case 1:Query(timetables,n);system("pause");break;//车辆信息查询

        case 2:TicketOrder(timetables, n);WritetoFile(timetables,n,LogFileName);

system("pause");break;//购买车票,并更改文件信息

        case 3:TicketDelete(timetables, n); WritetoFile(timetables,n,LogFileName);

system("pause");break;//退回车票,并更改文件信息

        case 4:WritetoFile(timetables,n,LogFileName); system("pause");           

            return ;//返回上级菜单

        }

    }

}

int MainWindowSelect()// 主菜单实现(即用户选择窗口)

{    //请仿照菜单设计练习实现本菜单}

int AdminWindowSelect()// 管理员菜单实现

{    //请仿照菜单设计练习实现本菜单}

int PassagerWindowSelect ( ) // 普通顾客菜单实现

{    //请仿照菜单设计练习实现本菜单}

2.菜单功能处理函数

对应于菜单功能的每一项,编写处理函数(可能需要调用其他函数)。在处理函数中,给出一些必要的输入输出信息提示,并实现相应的功能。

初始时,可将菜单处理函数的函数体设置为空函数体,把程序框架搭好,然后逐步添加处理代码。

对应于菜单功能的每一项,参照前面给出的菜单功能描述。处理函数的原型和实现说明如下:

(1)void Signin():管理员用户登录函数。在此函数中,提示用户输入用户密码(默认用户名为admin,密码为123),若输入正确,则进入管理员窗口;如错误,则反复要求输入用户密码。注意:输入密码时要进行密码保护操作,即将输入的字母变成*号。

(2)int ReadFromFile(Timetable *timetables,int n,char *filename):从文件filename中导入数据。如果该文件无法打开,给出报错信息,程序退出。如果该文件存在,则将文件中的数据读到数组timetables中,正确读取返回文件中包含车次的数目,否则返回-1。

(3)int AddBus(Timetable *timetables,int n):添加车次。首先给定要添加车辆的车次号,如果该车次号已经存在,则给出提示信息,并要求重新输入;如果该车次号不存在,依次输入该车次信息(发车时间(小时和分钟),固定的路线(起始站、终点站),大致的行车时间,固定的额定载客量),并返回该汽车站的车次总数;注意:未生成当天日志文件前,增加的车次当天有效,否则第二天有效。

(4)int WritetoFile(Timetable *timetables,int n,char *filename):将数组timetables中的数据写入到filename中。正确写入返回非-1的数。

(5)void ShowBusInfo(Timetable *timetables,int n, int idx):显示数组timetables中第idx(下标)个元素的信息;

(6)void ShowTimetable(Timetable *timetables,int n); 显示汽车站中所有车次信息,并按发车时间进行升序排序,在此函数中需要调用ShowBusInfo(Timetable *timetables,int n, int idx)函数。

(7)void Query(Timetable *timetables, int n):查询操作,可以按车次和终点站分别进行查询。执行时,要求输入要查找的车次或是终点站名,然后调用find()函数(重载)进行查找,若找到相应结果,则显示;若没有则给出提示。注意:当以终点站名查询时,结果可能为多条,此时要求按发车时间顺序进行输出。

(8)int find(Timetable *timetables,int n,char *no):按车次进行查询,若找到,则返回该车次所在数组中的下标;否则返回-1;

(9)int find(Timetable *timetables,int n,char *Last_station,int *b): 按终点站名查询。若找到,则在b中记录终点站为Last_station的所有车次在数组中对应的下标,并返回该汽车站终点站为Last_station的车次数;否则返回-1;

(10)int DelBus(Timetable *timetables,int n):注销车次。输入要注销的车次号,如果不存在给出提示信息,否则询问是否注销该车次,是则删除整条记录,并返回该汽车站的车次总数。注意:未生成当天日志文件前,注销的车次当天有效,否则第二天有效。

(11)void GenerateLogFileName(char *LogFileName):根据当天日期生成日志名(如2019-9-19.log)。

(12)int InitializaionPassagerMode(Timetable *timetables,char *LogFileName,char *filename):判断当天日志文件LogFileName是否存在,若不存在,则将filename中的内容读至timetables中(注意要将sold_number成员置为0)并将timetables中的信息写入LogFileName;若日志文件存在,则直接从LogFileName中读取数据至数组timetables中。

(13)void TicketOrder(Timetable *timetables,int n):购买车票。输入要购买的车次,如果该车次不存在,给出提示;如果该车次存在则输出该车次的信息。如果当前系统时间距发车时间少于10分钟或该车次票已全部售出,则提示不可买票;否则要求输入购买的车票数目,并判断剩余的票是否大于等于要购买的票数,如果是则可以买票,同时更改已售车票数。否则提示车票数不够。

(14)void TicketDelete(Timetable *timetables,int n):退票。输入要退票的车次,如果该车次不存在,给出提示;如果该车次存在则输出该车次的信息。如果当前时间距离发车时间不足10分钟或售票数为0,则提示不可退票;否则要求输入退票的数目,并判断售出的票是否大于等于要退的票数,如果是则给予退票,同时更改已售车票数,否则给出退票数目不对提示信息。

(15)int StopService(Timetable *timetables,int n,char *no); 判断车次号为no的车的发车时间离当前时间是否小于10分钟或是小于当前时间,若是则返回1,停止售票退票;否则返回0。该函数需要获取系统当前时间,需要使用localtime函数获取。函数实现见样例。

(16)void SortbyTime(Timetable *timetables, int n):将timetables中的元素按发车时间进行升序排序;

(17)int Quit():询问是否要退出整个系统(y/n),输入’y’或’Y’时返回1,否则返回0。

3. StopService()函数实现样例

int StopSevice(Timetable *timetables,int n,char *no)   //判断是否停止售退票,1:停止;0:不停止

{   

struct tm *local;       //时间结构体

time_t t;  //把当前时间给t

t=time(NULL);            

local = localtime(&t);      /获取当前系统时间

int i = find(timetables,n,no);

if ((local->tm_hour*60 + local->tm_min) + 10 < (timetables[i].hour*60+timetables[i].minute))

     return 0;     

return 1;

}

>>其他说明

1. 应完成上述规定的基本功能。

2. 可根据需要增加或修改功能,如果完成得好,可加分。增加的功能例如:

(1)管理员将每个月的所有日志信息进行汇总分析,统计某班次车辆一个月的信息,计算上客率等;

(2)在显示多个车辆信息时(如管理员账户显示全部信息)对数据进行其他标准(如按终点站名)的排序。

(3)自行设计增加其他功能。

3. 本题目也可以使用通过类的定义对数据及相应操作进行封装来实现。

我自己写的参考代码,及思维导图分析(仅供参考)

VS2010版(之后会以资源的形式再上传一次)

运行无碍,但算法还存在优化空间,欢迎大家批评指正

#include "stdafx.h"


#include<iostream>
#include<cstdlib>
#include<fstream>
#include<iomanip>
#include<cstring>
#include<conio.h>
#include<cmath>
using namespace std;

struct Timetable
{
    char no[10];//班次
    int hour;//发车时间,小时
    int minute;//发车时间,分钟
    char Starting_station[10];//始发站
    char Last_station[10];//终点站
    float time;//行车时长
    int fare;//票价
    int max_number;//最大载客量
    int sold_number;//已售票数
};

void Signin()//管理员登录函数
{
    cout<<"\n*****管理员登录验证*****\n"<<endl;
    char name[10],secret[10];
    do
    {
        cout<<"用户名:";
        cin>>name;
        cout<<"密码:";
        cin.sync();//清空cin输入流里面的内容
        int i=0;
        char ch;
        while(1)
        {
            ch=getch();//getch()为头文件<conic.h>里面一个函数,从键盘上读取一个字符
            if(ch=='\r')//  \r表示回车键
                break;
            else if(ch=='\b')//  \b表示退格键,此为允许用户输入时退格
            {
                cout<<"\b \b";
                i--;
            }
            else
            {
                secret[i++]=ch;//将读取的字符存入密码数组中
                cout<<"*";//密码保护实现
            }
            secret[i]='\0';//末尾增加结束标志
        }
        if(strcmp(name,"admin")==0&&strcmp(secret,"123")==0)//验证密码是否正确,验证成功则跳出循环,否则提示错误,一直输入
            break;
        else
            cout<<endl<<"\n***用户名/密码输入错误,请重新输入***\n"<<endl;
    }while(1);
    cout<<endl<<"\n*****验证成功*****\n"<<endl;
    system("pause");
}

int find(Timetable *timetables,int n,char *no)//按车次进行查询
{
    int idx;
    for(int i=0;i<n;i++)//顺序查找
    {
        if(strcmp(timetables[i].no,no)==0)
        {
            idx=i;
            return idx;//将查询到的车次下标存入idx;
        }
    }
    return -1;//没有找到
}

int find(Timetable *timetables,int n,char *Last_station,int *b)//按终点站名进行查询
{
    int j=0;
    for(int i=0;i<n;i++)
    {
        if(strcmp(timetables[i].Last_station,Last_station)==0)
            b[j++]=i;//终点站相同的可能有多个结果,存入数组
    }
    if(j>0)//判断是否查询到相应车次
        return j;
    else
        return -1;
}

void SortbyTime(Timetable *timetables,int n)
{
    int i,j,min;
    Timetable tmp;
    for(int i=0;i<n;i++)//冒泡排序
    {
        int hmin=24,mmin=60;//hmin,mmin为时间的最大值,等同于将数组第一个数赋值给它
        for(int j=i;j<n;j++)
        {
            if(hmin>timetables[j].hour)
            {
                min=j;
                hmin=timetables[j].hour;
                mmin=timetables[j].minute;
            }
            else if(hmin==timetables[j].hour)
            {
                if(hmin>timetables[j].minute)
                {
                    min=j;
                    mmin=timetables[j].minute;
                }
            }
        }
        tmp=timetables[i];
        timetables[i]=timetables[min];
        timetables[min]=tmp;
    }
}

int StopService(Timetable *timetables,int n,char *no)//判断是否停止售退票,1:停止;0:不停止
{
    struct tm *local;//时间结构体
    time_t t;//把当前时间给t
    t=time(NULL);
    local=localtime(&t);//获取当前系统时间
    int i=find(timetables,n,no);
    if((local->tm_hour *60+local->tm_min)+10<(timetables[i].hour*60+timetables[i].minute))
        return 0;
    return 1;
}

int ReadFromFile(Timetable *timetables,char *filename)
{
    ifstream readfromfile;
    readfromfile.open(filename);
    if(!readfromfile)
        return -1;
    int i=0;
    while(readfromfile.peek()!=EOF)
    {
        readfromfile>>timetables[i].no>>timetables[i].hour>>timetables[i].minute
               >>timetables[i].Starting_station>>timetables[i].Last_station
               >>timetables[i].time>>timetables[i].fare
               >>timetables[i].max_number>>timetables[i].sold_number;
        i++;
    }
    readfromfile.close();
    return i;
}

int AddBus(Timetable *timetables,int n)//增加车次信息
{
    Timetable timeb;//定义一个结构体存放用户端欲输入车次信息
    char yn='y';
    do
    {
        cout<<"请输入要添加的车辆的车次号:";
        cin>>timeb.no;
        int f;
        f=find(timetables,n,timeb.no);
        if(f!=-1)
            cout<<"\n***该车次号已经存在***\n"<<endl;
        else
        {
            cout<<"\n***该车次号不存在,请检查输入车次号是否正确***\n"<<endl;
            cout<<"是否重新输入车次号(Y/N):";
            cin>>yn;
        }
    }while(yn=='Y'||yn=='y');
    if(yn=='N'||yn=='n')
    {
        cout<<"\n***录入新车次"<<timeb.no<<"的信息***\n"<<endl;
        cout<<"发车时间(小时):";cin>>timeb.hour;
        cout<<"发车时间(分钟):";cin>>timeb.minute;
        cout<<"始发站:";cin>>timeb.Starting_station;
        cout<<"终点站:";cin>>timeb.Last_station;
        cout<<"行车时长:";cin>>timeb.time;
        cout<<"票价:";cin>>timeb.fare;
        cout<<"最大载客量:";cin>>timeb.max_number;
        timeb.sold_number=0;
        timetables[n]=timeb;
        return n+1;
    }
    else
        return n;
}

int WritetoFile(Timetable *timetables,int n,char *filename)
{
    int i=0;
    ofstream writetofile;
    writetofile.open(filename);
    if(!writetofile.is_open())
    {
        cout<<"\n***无法打开文件"<<filename<<"***\n"<<endl;
        return 1;
    }
    else
        for(i=0;i<n;++i)
        {
            writetofile<<timetables[i].no<<'\t'<<timetables[i].hour<<'\t'<<timetables[i].minute<<'\t'
                       <<timetables[i].Starting_station<<'\t'<<timetables[i].Last_station<<'\t'
                          <<timetables[i].time<<'\t'<<timetables[i].fare<<'\t'
                       <<timetables[i].max_number<<'\t'<<timetables[i].sold_number;
            if(i<n-1)
                writetofile<<endl;
        }
        writetofile.close();
    return 0;//返回0表示成功
}

void numbertochar(int number,char *str)//****************把数字转换成字符数组((新定义函数))
{
    int i=0,j;
    if(number!=0)
    {
        do
        {
            str[i++]=number%10+'0';
            number/=10;
        }while(number!=0);
        str[i]='\0';
    i-=1;
    }
    else
    {
        str[0]='0';
        str[1]='0';
        str[2]='\0';
        i=1;
    }
    char t;
    for(j=0;j<i;j++,i--)
    {
        t=str[i];
        str[i]=str[j];
        str[j]=t;
    }
}

void ShowBusInfo(Timetable *timetables,int idx)//显示指定下标的的车辆的全部信息
{
    int n=ReadFromFile(timetables,"bus.txt");
    char h[21]="",m[11]="";
    numbertochar(timetables[idx].hour,h);
    numbertochar(timetables[idx].minute,m);
    strcat(h,":");
    strcat(h,m);
    cout<<setw(7)<<timetables[idx].no<<setw(10)<<h<<'\t'
        <<timetables[idx].Starting_station<<setw(10)<<timetables[idx].Last_station<<setw(10)
        <<timetables[idx].time<<setw(11)<<timetables[idx].fare<<setw(10)
        <<timetables[idx].max_number<<setw(12)<<timetables[idx].sold_number;
    int yn=StopService(timetables,n,timetables[idx].no);
    if(yn==1)
        cout<<setw(15)<<"停止检票\0"<<endl;
    else
        cout<<setw(11)<<"候车\0"<<endl;
}

void ShowTimetableTitle()                  //            ******************((新定义函数))
{
    cout<<setw(8)<<"车次"<<setw(12)<<"发车时间"
        <<setw(10)<<"起点站"<<setw(10)<<"终点站"
        <<setw(12)<<"行车时间"<<setw(8)<<"票价"
        <<setw(12)<<"额定载量"<<setw(12)<<"已售票数"<<setw(8)<<"备注"<<endl;
}

void ShowTimetable(Timetable *timetables,int n)//显示全部车次信息
{
    ShowTimetableTitle();
    SortbyTime(timetables,n);
    WritetoFile(timetables,n,"bus.txt");
    for(int i=0;i<n;i++)
        ShowBusInfo(timetables,i);
}

void Query(Timetable *timetables,int n)//查询操作,可以按车次和终点站名分别进行查询
{
    cout<<"\n*****车辆信息查询界面*****\n"<<endl;
    cout<<"请输入需要查找的车次或是终点站名:";
    char search[20];
    cin>>search;
    int result1,f2,result2[20];
    result1=find(timetables,n,search);
    f2=find(timetables,n,search,result2);
    if(result1==-1&&f2==-1)
    {
        cout<<"\n***未查找到相应车辆信息***\n"<<endl;
        return;
    }
    else if(result1!=-1&&f2==-1)
    {
        cout<<"\n***车次"<<search<<"全部信息如下***\n"<<endl;
        ShowTimetableTitle();
        ShowBusInfo(timetables,result1);
        system("pause");
        return;
    }
    else
    {
        cout<<"\n***查询到终点站为"<<search<<"的车辆信息如下***\n"<<endl;
        ShowTimetableTitle();
        for(int j=0;j<f2;j++)
            {
                ShowBusInfo(timetables,result2[j]);
            }
        system("pause");
        return;
    }
}

int DelBus(Timetable *timetables,int n)
{
    cout<<"\n*****车次注销界面*****\n"<<endl;
    char no[10];//用于存放用户端输入的车次
    int f,outloop,idx;
    char choice;
    Timetable timeb;//中间变量
    do
    {
        cout<<"请输入要删除的车次:";
        cin>>no;
        f=find(timetables,n,no);
        if(f!=-1)//需要删除的车次存在
        {
            idx=f;
            cout<<"\n***车次"<<no<<"存在***\n";
            cout<<"车次"<<no<<"的全部信息:"<<endl;
            ShowTimetableTitle();
            ShowBusInfo(timetables,idx);
            cout<<"是否确认删除(Y/N):";
            cin>>choice;
            outloop=0;
        }
        else
        {
            cout<<"\n***该车次号"<<no<<"的信息不存在,请检查输入车次是否正确***\n"<<endl;
            outloop=1;
        }
    }while(outloop==1);
    if(choice=='Y'||choice=='y')
    {
        cout<<"\n***注销成功***\n"<<endl;
        for(int i=idx;i<n-1;i++)//从查询到的下标idx处,逐一前移,将要删除的车次信息排到末尾
        {
            timeb=timetables[i];
            timetables[i]=timetables[i+1];
            timetables[i+1]=timeb;
        }
        n=n-1;
    }
    else
        cout<<"\n***取消删除***\n"<<endl;
    return n;
}

void GenerateLogFileName(char *LogFileName)//根据当天日期生成日志名(如 2019-9-19.log)
{
    LogFileName[0]='\0';
    struct tm*local;//时间结构体
    time_t t;//把当前时间给t
    t=time(NULL);
    local=localtime(&t);//获取当前系统时间
    char year[5],month[3],day[3];
    numbertochar(1900+local->tm_year,year);
    numbertochar(1+local->tm_mon,month);
    numbertochar(local->tm_mday,day);
    strcat(LogFileName,year);
    strcat(LogFileName,"-");
    strcat(LogFileName,month);
    strcat(LogFileName,"-");
    strcat(LogFileName,day);
    strcat(LogFileName,".log");
}

int InitializationPassagerMode(Timetable *timetables,char *LogFileName,char *filename)//判断当天日志文件LogFileName是否存在。
{
    int n=0;
    ofstream out;
    out.open(LogFileName);
    n=ReadFromFile(timetables,filename);
    if(!out)
    {
        cout<<"\n***当天的日志文件"<<LogFileName<<"不存在***\n"<<endl;
        ifstream readfromfile;
        readfromfile.open(filename);
        if(!readfromfile)
            return -1;
        int i=0;
        while(readfromfile.peek()!=EOF)//将filename中的内容读至timetables中
        {
            readfromfile>>timetables[i].no>>timetables[i].hour>>timetables[i].minute
                        >>timetables[i].Starting_station>>timetables[i].Last_station
                        >>timetables[i].time>>timetables[i].fare
                        >>timetables[i].max_number;
            timetables[i].sold_number=0;//sold_number成员置为0
            i++;
        }
        readfromfile.close();
        WritetoFile(timetables,n,LogFileName);//将timetables中的信息写入LogFileName
    }
    else//直接从LogFileName中读取数据至数组timetables中
        for(int j=0;j<n;j++)
        {
            out<<timetables[j].no<<'\t'<<timetables[j].hour<<'\t'<<timetables[j].minute<<'\t'
                <<timetables[j].Starting_station<<'\t'<<timetables[j].Last_station<<'\t'
                <<timetables[j].time<<'\t'<<timetables[j].fare<<'\t'
                <<timetables[j].max_number<<'\t'<<timetables[j].sold_number<<'\t';           
            if(j<n-1)
                out<<endl;
            else;
        }
    out.close();
    return n;
}

void TicketOrder(Timetable *timetables,int n)//购买车票
{
    cout<<"\n*****购票界面*****\n"<<endl;
    char no[10];
    int f;
    bool t=true;
    int number,left,yn,YN;
    do
    {
        cout<<"请输入要购买的车次:";
        cin>>no;
        f=find(timetables,n,no);
        if(f==-1)
        {
            cout<<"\n***该车次不存在/输入错误,***\n"<<endl;
            return;
        }
        else
            t=false;
    }while(t);
    if(t==false)
    {
        cout<<"\n***车次"<<no<<"存在***\n"<<endl;
        cout<<"车次"<<no<<"的全部信息如下:"<<endl;
        ShowTimetableTitle();
        ShowBusInfo(timetables,f);
        yn=StopService(timetables,n,no);
        left=timetables[f].max_number-timetables[f].sold_number;
        if(yn==1&&left>0)
            cout<<"\n***现在距离发车时间少于10分钟,不可买票***\n"<<endl;
        else if(left==0)
            cout<<"\n***该车次票已经全部售出,不可买票***\n"<<endl;
        else
        {
            cout<<"请输入需要购买的车票数目:";
            cin>>number;
            if(left>=number)
            {
                timetables[f].sold_number+=number;
                cout<<"\n***购买成功***\n"<<endl;
            }
            else
                cout<<"\n***车票仅剩"<<left<<"张,请选择其他班次***\n"<<endl;
            return;
        }
    }
}

void TicketDelete(Timetable *timetables,int n)
{
    cout<<"\n*****退票界面*****\n"<<endl;
    char no[10],again;
    bool t=true;
    int f,x,num;
    do
    {
        do
        {
            cout<<"请输入要退票的车次:";
            cin>>no;
            f=find(timetables,n,no);
            x=StopService(timetables,n,no);
            if(f==-1)//判断该车次是否存在
            {
                cout<<"\n***该车次不存在/输入错误***\n";
                cout<<"是否重新输入(Y/N):"<<endl;
                cin>>again;
                if(again=='n'||again=='N')
                    return;
            }
            else
            {
                if(x==1)
                {
                    cout<<"\n***该车次已停止服务***\n"<<endl;
                    return;
                }
                else
                    t=false;//车次存在且继续服务
                again='y';
            }
        }while(again=='n'||again=='N');    
    }while(t);
    char yn;
    if(t==false)
    {
        do
        {
            cout<<"\n***请确认退票信息***\n"<<endl;
            ShowTimetableTitle();
            ShowBusInfo(timetables,f);//显示要删除的车次的基础信息
            cout<<"请输入需要退票的数量:"<<endl;
            cin>>num;
            if(num>timetables[f].sold_number)
            {
                cout<<"\n***退票数大于购票数,请重新确认退票数量***\n"<<endl;
                cout<<"是否继续退票(Y/N):";
                cin>>yn;
            }
            else
            {
                timetables[f].sold_number-=num;
                cout<<"\n***退票成功***\n"<<endl;
                return;
            }
        }while(yn=='y'||yn=='Y');
        if(yn=='n'||yn=='N')
        {
            cout<<"\n***取消退票***\n"<<endl;
            return;
        }
    }
}

int Quit()
{
    cin.sync();
    cout<<"是否要退出整个系统(y/n):";
    char c;
    cin>>c;
    if(c=='y'||c=='Y')
        return 1;
    else
        return 0;
}

int MainWindowSelect()//主菜单实现
{
    cout<<"\n*****主菜单*****\n"<<endl;
    char *m[4]={"1.管理员登录",
                "2.普通顾客登录",
                "3.退出"}; 
    int i=0;
    while(m[i])
    {
        cout<<m[i]<<endl;
        i++;
    }
    cout<<"\n****************\n"<<endl;
    cout<<"请输入选择:";
    int n;
    do
    {
        cin>>n;
    }while(n<0||n>3);
    return n;
}

int AdminWindowSelect()//管理员菜单实现
{
    cout<<"\n*****管理员菜单*****\n"<<endl;
    char *m[6]={"1.增加车次信息",
                "2.查看所有车次信息",
                "3.车辆信息查询",
                "4.注销车次",
                "5.退出"};
    for(int i=0;m[i];i++)
        cout<<m[i]<<endl;
    cout<<"\n********************\n"<<endl;
    cout<<"请输入选择:";
    int n;
    do
    {
        cin>>n;
    }while(n<0||n>5);
    return n;
}

int PassagerWindowSelect()//普通顾客菜单实现
{
    cout<<"\n*****普通顾客菜单*****\n"<<endl;
    char *m[5]={"1.车辆信息查询",
                "2.购买车票",
                "3.退票",
                "4.退出"};
    for(int i=0;m[i];i++)
        cout<<m[i]<<endl;
    cout<<"\n**********************\n"<<endl;
    cout<<"请输入选择:";
    int n;
    do
    {
        cin>>n;
    }while(n<0||n>4);
    return n;
}

void AdminMode( Timetable *timetables,char *filename )//管理员模式
{
    Signin();//登录
    int n=ReadFromFile(timetables,"bus.txt");
    while(1)
    {
        system("cls");
        int AdminChoice = AdminWindowSelect();
        switch(AdminChoice)
        {
        case 1:
            system("cls");
            n = AddBus(timetables,n);
            WritetoFile(timetables,n,filename);//增加车次信息,并及时写到文件中
            system("pause");
            break;
        case 2:
            system("cls");
            ShowTimetable(timetables,n);//浏览时刻表
            system("pause");
            break;
        case 3:
            system("cls");
            Query(timetables,n);//车辆信息查询
            system("pause");
            break;
        case 4:
            system("cls");
            n = DelBus(timetables,n);
            system("pause");
            WritetoFile(timetables,n,filename);//注销车次,并及时更改文件
            break;
        case 5:
            system("cls");
            WritetoFile(timetables,n,filename);//返回上级菜单,并将信息保存回 bus.txt 文件
            return;
        }
    }
}

void PassagerMode( Timetable *timetables,char *filename )//乘客模式
{
    char LogFileName[200];
    GenerateLogFileName(LogFileName);//根据当前日期生成日志名
    int n = InitializationPassagerMode(timetables,LogFileName,filename);
    n=ReadFromFile(timetables,"bus.txt");
    int PassagerChoice;
    while(1)
    {
        system("cls");
        switch(PassagerChoice = PassagerWindowSelect())
        {
        case 1:
            system("cls");
            Query(timetables,n);//车辆信息查询
            system("pause");
            break;
        case 2:
            system("cls");
            TicketOrder(timetables,n);
            WritetoFile(timetables,n,filename);//购买车票,并更改文件信息
            system("pause");
            break;
        case 3:
            system("cls");
            TicketDelete(timetables,n);
            WritetoFile(timetables,n,filename);//退回车票,并更改文件信息
            system("pause");
            break;
        case 4:
            system("cls");
            WritetoFile(timetables,n,filename);
            return;//返回上级菜单
        }
    }
}

int main()
{
    int UserChoice;
    Timetable timetables[100];
    while(1)
    {
        switch( UserChoice = MainWindowSelect() )//用户选择窗口
        {
        case 1: 
            system("cls");
            AdminMode(timetables,"bus.txt");//进入管理员窗口
            break;
        case 2:
            system("cls");
            PassagerMode(timetables,"bus.txt");//进入乘客窗口
            break;
        case 3:
            system("cls");
            if(Quit()!=1)
                continue;
        }
        if(UserChoice==3)
            break;
    }
    return 0;
}

#include <iostream> #include <fstream> #include <string> #include<time.h> using namespace std; void welcome(); //欢迎子函数 void choose(); //选择子函数 void banciluru(); //班次录入子函数 void liulanbancixinxi(); //浏览班次信息子函数 void shoupiao(); //售票子函数 void tuipiao(); //退票子函数 void quit(); //退出子函数 void chaxun(); //查询子函数 int loading(); //文件载入子函数 const int MAX=20; //使数组最大值可调 const int N=50; struct time //时间结构体,为了与系统时间做比较. { int hour; int minutes; }; struct ticket //车票结构体,包含车次,时间结构体,起点,终点,行车时间,额定载客量,已订票人数 { int Number; struct time Setout; char Qidian[MAX]; char Zhongdian[MAX]; float Lasttime; int Fixnumber; int Fixednumber; }car[N]; //主函数 int main() { welcome(); return 0; } //欢迎子函数 void welcome() { cout<<"________________________________________________________"<<endl; cout<<"| 欢 * 迎 * 使 * 用 * 火 * 车 * 票 * 管 * 理 * 系 * 统 |"<<endl; cout<<"| |"<<endl; cout<<"| 本管理系统有以下功能: |"<<endl; cout<<"| |"<<endl; cout<<"| 1 班次录入 |"<<endl; cout<<"| 2 浏览班次信息 |"<<endl; cout<<"| 3 查询火车信息 |"<<endl; cout<<"| 4 购买火车票 |"<<endl; cout<<"| 5 退订火车票 |"<<endl; cout<<"| 6 退出系统 |"<<endl; cout<<"|______________________________________________________|"<<endl; cout<<"请输入所要执行功能前的数字: "<<endl; choose(); } //选择子函数 void choose() { string i; cin>>i; if(i=="1") banciluru(); if(i=="2") liulanbancixinxi(); if(i=="3") chaxun(); if(i=="4") shoupiao(); if(i=="5") tuipiao(); if(i=="6") quit(); else { cout<<"输入有误!请在数字1-5之间重新您的输入选择!"<<endl; choose(); } } //班次录入子函数 void banciluru() { string t="1"; ofstream outfile; outfile.open("班次信息.txt",ios::app); for(int i=0;t=="1";i++) { cout<<"请输入需要添加的火车班次:"<<endl; cin>>car[i].Number; cout<<"请输入此班次发车时间(格式:先输入小时,回车,再输入分钟):"<<endl; cin>>car[i].Setout.hour; cin>>car[i].Setout.minutes; cout<<"请输入出发站:"<<endl; cin>>car[i].Qidian; cout<<"请输入终点站:"<<endl; cin>>car[i].Zhongdian; cout<<"请输入行车时间:"<<endl; cin>>car[i].Lasttime; cout<<"请输入额定载客量:"<<endl; cin>>car[i].Fixnumber; cout<<"请输入已订票人数:"<<endl; cin>>car[i].Fixednumber; outfile<<car[i].Number<<" "<<car[i].Setout.hour<<" "<<car[i].Setout.minutes<<" "<<car[i].Qidian<<" "<<car[i].Zhongdian<<" "<<car[i].Lasttime<<" "<<car[i].Fixnumber<<" "<<car[i].Fixednumber<<endl; cout<<"是否继续录入?(是请输1,否请输任意键返回主菜单)"<<endl; cin>>t; if(t!="1") { welcome(); } } outfile.close(); cout<<"输入回车键返回"<<endl; getchar(); getchar(); welcome(); } //浏览班次子函数 void liulanbancixinxi() { int c; c=loading(); cout<<"班次"<<" "<<"发车时间"<<" "<<"起点站"<<" "<<"终点站"<<" "<<"行车时间"<<" "<<"额定载客量"<<" "<<"已订票人数"<<endl; for(int i=0;i<c;i++) { cout<<car[i].Number<<" "<<car[i].Setout.hour<<":"<<car[i].Setout.minutes<<" "<<car[i].Qidian<<" "<<car[i].Zhongdian<<" "<<car[i].Lasttime<<" "<<car[i].Fixnumber<<" "<<car[i].Fixednumber<<endl; time_t tval; struct tm *now; tval = time(NULL); now = localtime(&tval); if((now->tm_hour==car[i].Setout.hour&&now->tm_min>car[i].Setout.minutes)||(now->tm_hour>car[i].Setout.hour)) cout<<"此车已发出"<<endl; } cout<<"输入回车键返回"<<endl; getchar(); getchar(); welcome(); } //车次查询子函数 void Numbersearch(); void Finalsearch(); void chaxun() { string t; cout<<"1.按班次查询"<<endl; cout<<"2.按终点站查询"<<endl; cout<<"请输入您想选择的查询方法前的数字:"<<endl; cin>>t; if(t=="1") Numbersearch(); if(t=="2") Finalsearch(); if(t!="1"||t!="2") { cout<<"输入有误,请重新输入"<<endl; chaxun(); } }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chhanz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值