目录
一、需求分析
1.1需求分析
随着新时代的到来,人口流动激增,加大了人们对车票的需求。在信息化时代的背景下,一种新型的车票管理系统成为人们的急需。本系统使用高效、便捷,极大地提高了乘客购买车票与管理员管理车票的效率,增强了使用者的使用体验感,是新时代必不可少的管理系统。从管理员的角度,我们提供了增加车次、删减车次、对某一车次的某一具体信息(包括但不限于余票、发车时间、最大载客量)进行修改的功能。从消费者的角度,我们可提供注册账号、通过某一信息(包括但不限于车次、发车地点、目的地)查询车票、购买车票、退票、查询已购买车票等功能。且本系统各界面的菜单经过了精心设计,极大地提高了用户的使用舒适度,让使用者在清晰、不臃肿的环境下使用本程序。
1.2系统功能
二、系统实现
2.1TicketManageSystemMain
主模块main()
1模块功能:通过调用菜单模块选择对应的程序执行。
2输入输出:
归属:TicketManageSystemMain
3模块代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include "Menu.h"
#include "System.h"
#include "User.h"
#include "Manager.h"
int main()
{
int no = 0;
int no2 = 0;
Ticket tic[100];
User us[100];
while (1)
{
system("cls");//清屏
no = duQuShuJu(tic);//车票数据使用文本文件保存
no2 = duQuUser(us);//用户账号密码使用二进制文件保存
switch (loginMenu())
{
case 1:managerDenRu(tic,&no); break;
case 2:userDengRu(tic,&no); break;
case 3:zhuCe(us,&no2); break;
case 4:; exit(0);
default:printf("输入错误");
}
}
return 0;
}
2.2Manager
2.2.1自定义模块 managerDenRu
1模块功能:管理员登录
2输入输出:
形式:void managerDenRu(Ticket* pTic,int* no)
归属:Manager
3模块代码:
void managerDenRu(Ticket* pTic,int* no)//管理员登录模块,管理员账户需要在文本文件内添加
{
Manager n;
Manager arr[100];
int i = 0;
int j = 0;
bool flag1 = 1;
FILE* pRead = fopen("manager.txt", "r");
if (pRead == NULL)//打开失败
{
printf("%s\n", strerror(errno));
}
else//打开成功
{
while (1)
{
if (fscanf(pRead, "%s%s", &arr[i].id, &arr[i].password) != 2)
{
break;
}
i++;
}
fclose(pRead);//关闭文件
pRead = NULL;
}
while (flag1)
{
printf("请输入用户名>");
scanf("%s", n.id);
printf("请输入密码:");
int k = 0;
char ch;
while ((ch = _getch()) != '\r')//输入密码时实时显示*
{
if (ch == '\b' && i > 0)
{
printf("\b \b");
--i;
}
else if (ch != '\b')
{
n.password[k++] = ch;
printf("*");
}
}
n.password[k] = '\0';
for (j = 0; j <= i; j++)
{
if (!strcmp(n.id, arr[j].id))//用户名正确
{
if (!strcmp(n.password, arr[j].password))//密码正确
{
system("cls");
printf("登录成功!\n");
while (flag1)
{
switch (managerChoiceMenu1())
{
case 1:addCheCi(pTic, no); break;//增加车次
case 2:delCheCi(pTic, no); break;//删除车次
case 3:modifyXinXi(pTic,*no); break;//修改车次信息
case 4:flag1 = 0; break;//退出登录
default:printf("输入错误");
}
}
break;
}
else
{
printf("\n密码输入错误!\n");
flag1 = fanHuiMenu();
break;
}
}
}
if (strcmp(n.id, arr[j].id))
{
printf("账号输入错误!\n");
flag1 = fanHuiMenu();
}
}
}
2.2.2自定义模块 addCheCi
1模块功能:添加列车
2输入输出:
形式:void addCheCi(Ticket* pTic,int* no)
归属:Manager
3模块代码:
void addCheCi(Ticket* pTic,int* no)//添加车次模块
{
printf("如有大量数据请通过文本文件添加\n");
printf("请输入新增车次的车次号、发车时间、始发站、终点站、行车时间及最大载客量、列车日期>");
scanf("%s%s%s%s%d%d%s", &pTic[*(no)].num, &pTic[*(no)].time1, &pTic[*(no)].name1, &pTic[*(no)].name2, &pTic[*(no)].time2, &pTic[*(no)].peomax,&pTic[*(no)].rq);
pTic[*(no)].peo = 0;
*(no) = *(no)+1;
FILE* pWrite = fopen("ticket.txt", "w");
if (pWrite == NULL)//打开失败
{
printf("%s\n", strerror(errno));
}
else//打开成功
{
int i = 0;
for (i = 0; i < *no; i++)
{
fprintf(pWrite, "%s %s %s %s %d %d %d %s ", (pTic+i)->num, (pTic + i)->time1, (pTic + i)->name1, (pTic + i)->name2, (pTic + i)->time2, (pTic + i)->peomax, (pTic + i)->peo, (pTic + i)->rq);
}
fclose(pWrite);//关闭文件
pWrite = NULL;
printf("添加成功!\n");
while (getchar() != '\n')//清空输入缓冲区
{
continue;
}
}
}
2.2.3自定义模块 delCheCi
1模块功能:删除车次
2输入输出:
形式:void delCheCi(Ticket* pTic, int* no)
归属:Manager
3模块代码:
void delCheCi(Ticket* pTic, int* no)//删除车次模块
{
char No[10];
char choice;
int k;
while (getchar(),printf("还要删除数据吗?(y/n)\n"), scanf("%c", &choice), choice == 'y')
{
printf("请输入要删除车次的车次号>");
scanf("%s", No);
for (k = 0; k <= *no; k++)
{
if (!strcmp((pTic+k)->num,No))
{
break;
}
}
for (int i = k; i <= *no; i++)
{
pTic[i] = pTic[i + 1];
}
(*no)--;
FILE* pWrite = fopen("ticket.txt", "w");
if (pWrite == NULL)//打开失败
{
printf("%s\n", strerror(errno));
}
else//打开成功
{
int i = 0;
for (i = 0; i < *no; i++)
{
fprintf(pWrite, "%s %s %s %s %d %d %d %s ", (pTic + i)->num, (pTic + i)->time1, (pTic + i)->name1, (pTic + i)->name2, (pTic + i)->time2, (pTic + i)->peomax, (pTic + i)->peo, (pTic + i)->rq);
}
fclose(pWrite);//关闭文件
pWrite = NULL;
printf("删除成功!\n");
}
}
}
2.2.4自定义模块 modifyXinXi
1模块功能:列车信息修改
2输入输出:
形式:void modifyXinXi(Ticket* pTic,int no)
归属:Manager
3模块代码:
void modifyXinXi(Ticket* pTic,int no)//信息修改模块
{
int k;
char No[10];
bool flag = 0;
printf("请输入要修改信息的车次号>");
scanf("%s", No);
for (k = 0; k <= no; k++)
{
if (!strcmp((pTic + k)->num, No))
{
flag = 1;
break;
}
}
if (flag == 0)
{
printf("查询不到次车次,请在核实后重新输入\n");
}
else
{
switch (modifyMenu())
{
case 1:
{
printf("请输入发车时间>");
scanf("%s", pTic[k].time1);
break;
}//发车时间
case 2:
{
printf("请输入始发站>");
scanf("%s", pTic[k].name1);
break;
}//始发站
case 3:
{
printf("请输入终点站>");
scanf("%s", pTic[k].name2);
break;
}//终点站
case 4:
{
printf("请输入最大载客量>");
scanf("%d", &pTic[k].peomax);
break;
}//最大载客量
case 5:
{
printf("请输入订票人数>");
scanf("%d", &pTic[k].peo);
break;
}订票人数
default:printf("输入错误");
}
FILE* pWrite = fopen("ticket.txt", "w");
if (pWrite == NULL)//打开失败
{
printf("%s\n", strerror(errno));
}
else//打开成功
{
int i = 0;
for (i = 0; i < no; i++)
{
fprintf(pWrite, "%s %s %s %s %d %d %d %s ", (pTic + i)->num, (pTic + i)->time1, (pTic + i)->name1, (pTic + i)->name2, (pTic + i)->time2, (pTic + i)->peomax, (pTic + i)->peo, (pTic + i)->rq);
}
fclose(pWrite);//关闭文件
pWrite = NULL;
printf("修改成功!\n");
}
}
}
2.3 System
2.3.1自定义模块 duQuShuJu
1模块功能:读取每趟列车的信息
2输入输出:
形式:int duQuShuJu(Ticket* pTic)
归属:System
3模块代码
#define _CRT_SECURE_NO_WARNINGS 1
#include"Manager.h"
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include"User.h"
int duQuShuJu(Ticket* pTic)
{
FILE* pRead = fopen("ticket.txt", "r");
if (pRead == NULL)//打开失败
{
printf("%s\n", strerror(errno));
}
else//打开成功
{
int i = 0;
while (1)
{
if (fscanf(pRead, "%s%s%s%s%d%d%d%s", &pTic[i].num, &pTic[i].time1, &pTic[i].name1, &pTic[i].name2, &pTic[i].time2, &pTic[i].peomax, &pTic[i].peo, &pTic[i].rq) != 8)
{
break;
}
i++;
}
fclose(pRead);//关闭文件
pRead = NULL;
return i;
}
}
2.3.2自定义模块 duQuUser
1模块功能:读取乘客信息
2输入输出:
形式:int main()
归属:TicketManageSystemMain
3模块代码
int duQuUser(User* us)
{
FILE* pRead = fopen("user.data", "rb");
if (pRead == NULL)//打开失败
{
printf("%s\n", strerror(errno));
}
else//打开成功
{
int i = 0;
while (1)
{
if (fread((void*)&us[i], sizeof(struct User), 1, pRead) != 1)
{
break;
}
i++;
}
fclose(pRead);//关闭文件
pRead = NULL;
return i;
}
}
2.4 User
2.4.1注册账号模块zhuCe
1模块功能:新用户进行信息注册
2输入输出:
形式:void zhuCe(User* us,int* no)
归属:User
3模块代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include "User.h"
#include "Menu.h"
#include "Manager.h"
#include "System.h"
void zhuCe(User* us,int* no)//注册账号模块
{
while (1)
{
bool flag = 1;
printf("请输入用户名(10位以内的数字或字母组成)>");
scanf("%s", us[*no].id);
int x = 0;
for (x = 0; x < *no; x++)
{
if (!strcmp(us[*no].id, us[x].id))
{
printf("该用户名已存在,请重新注册\n");
flag = 0;
break;
}
}
if (flag == 0)
{
break;
}
else
{
printf("请输入密码(20位以内的数字或字母组成)>");
scanf("%s", us[*no].password);
*(no) = *(no)+1;
FILE* pWrite = fopen("user.data", "wb");
if (pWrite == NULL)//打开失败
{
printf("%s\n", strerror(errno));
}
else//打开成功
{
int i = 0;
fwrite((void*)us, sizeof(struct User), *no, pWrite);
fclose(pWrite);//关闭文件
pWrite = NULL;
printf("注册成功!\n");
while (getchar() != '\n')//清空输入缓冲区
{
continue;
}
break;
}
}
}
}
2.4.2登录模块userDengRu
2输入输出:
形式:void userDengRu(Ticket* pTic, int* no)
归属:User
3模块代码:
void userDengRu(Ticket* pTic, int* no)//用户登录模块
{
User n;
User arr[100];
int i = 0;
int j = 0;
bool flag1 = 1;
FILE* pRead = fopen("user.data", "rb");
if (pRead == NULL)//打开失败
{
printf("%s\n", strerror(errno));
}
else//打开成功
{
while (1)
{
if (fread((void*)&arr[i], sizeof(struct User), 1, pRead) != 1)
{
break;
}
i++;
}
fclose(pRead);//关闭文件
pRead = NULL;
}
while (flag1)
{
printf("请输入用户名>");
scanf("%s", n.id);
/*printf("请输入密码>");
scanf("%s", n.password);*/
printf("请输入密码:");
int k = 0;
char ch;
while ((ch = _getch()) != '\r')//输入密码时实时显示*
{
if (ch == '\b' && i > 0)
{
printf("\b \b");
--i;
}
else if (ch != '\b')
{
n.password[k++] = ch;
printf("*");
}
}
n.password[k] = '\0';
for (j = 0; j <= i; j++)
{
if (!strcmp(n.id, arr[j].id))
{
if (!strcmp(n.password, arr[j].password))
{
system("cls");
printf("登录成功!\n");
while (flag1)
{
while (getchar() != '\n')//清空输入缓冲区
{
continue;
}
switch (userChoiceMenu1())
{
case 1:chaXun(pTic, no); break;//查询
case 2:maiTicket(pTic, no); break;//购买
case 3:tuiTicket(pTic, no); break;//退票
case 4:flag1 = 0; break;//退出登录
default:printf("输入错误");
}
}
break;
}
else
{
printf("\n密码输入错误!\n");
flag1 = fanHuiMenu();
break;
}
}
}
if (strcmp(n.id, arr[j].id))
{
printf("账号输入错误!\n");
flag1 = fanHuiMenu();
}
}
}
2.4.3 查询模块chaXun
1模块功能:显示查询的方法进行选择
2输入输出:
形式:void chaXun(Ticket* pTic, int* no)
归属:User
3模块代码:
void chaXun(Ticket* pTic, int* no)//查询车票模块
{
while (getchar() != '\n')//清空输入缓冲区
{
continue;
}
switch (userChoiceMenu2())
{
case 1:chaXunMuDiDi(pTic, no); break;//目的地
case 2:chaXunQiDian(pTic, no); break;//起点
case 3:chaXunCheCi(pTic, no); break;//车次信息
default:printf("输入错误");
}
}
2.4.4查询目的地模块chaXunMuDiDi
1模块功能:通过目的地的信息对火车进行查找
2输入输出:
形式:void chaXunMuDiDi(Ticket* pTic, int* no)
归属:User
3模块代码:
void chaXunMuDiDi(Ticket* pTic, int* no)
{
while (getchar() != '\n')//清空输入缓冲区
{
continue;
}
int k;
char Name[20];
printf("请输入要查询的目的地>");
scanf("%s", Name);
printf("车次 出发时间 起始点 目的地 行驶时间 余票 发车时间\n");
for (k = 0; k < *no; k++)
{
if (!strcmp((pTic + k)->name2, Name))
{
printf("%s %s %s %s %d %d %s\n", pTic[k].num, pTic[k].time1, pTic[k].name1, pTic[k].name2, pTic[k].time2, (pTic[k].peomax) - (pTic[k].peo), pTic[k].rq);
}
}
}
2.4.5查询起点地信息模块chaXunQiDian
1模块功能:通过目的地的信息对火车进行查找
2输入输出:
形式:void chaXunQiDian(Ticket* pTic, int* no)
归属:User
3模块代码:
void chaXunQiDian(Ticket* pTic, int* no)
{
while (getchar() != '\n')//清空输入缓冲区
{
continue;
}
int k;
char Name[20];
printf("请输入要查询的起始点>");
scanf("%s", Name);
printf("车次 出发时间 起始点 目的地 行驶时间 余票 发车时间\n");
for (k = 0; k < *no; k++)
{
if (!strcmp((pTic + k)->name1, Name))
{
printf("%s %s %s %s %d %d %s\n", pTic[k].num, pTic[k].time1, pTic[k].name1, pTic[k].name2, pTic[k].time2, (pTic[k].peomax) - (pTic[k].peo), pTic[k].rq);
}
}
}
2.4.6查询车次模块chaXunCheCi
1模块功能:通过车次的信息对火车进行查找
2输入输出:
形式:void chaXunCheCi(Ticket* pTic, int* no)
归属:User
void chaXunCheCi(Ticket* pTic, int* no)
{
while (getchar() != '\n')//清空输入缓冲区
{
continue;
}
int k;
char No[10];
bool flag = 0;
printf("请输入要查询的车次号>");
scanf("%s", No);
for (k = 0; k < *no; k++)
{
if (!strcmp((pTic + k)->num, No))
{
flag = 1;
break;
}
}
if (flag == 0)
{
printf("查询不到次车次,请在核实后重新输入\n");
}
else
{
printf("车次 出发时间 起始点 目的地 行驶时间 余票 发车时间\n");
printf("%s %s %s %s %d %d %s\n", pTic[k].num, pTic[k].time1, pTic[k].name1, pTic[k].name2, pTic[k].time2, (pTic[k].peomax) - (pTic[k].peo), pTic[k].rq);
}
}
2.4.7购票模块maiTicket
1模块功能:输入购票信息购买车票
2输入输出:
形式:void maiTicket(Ticket* pTic, int* no)
归属:User
3模块代码
void maiTicket(Ticket* pTic, int* no)
{
int k;
char No[10];
char input;
bool flag = 0;
printf("请输入您要购买车票的车次号>");
scanf("%s", No);
for (k = 0; k < *no; k++)
{
if (!strcmp((pTic + k)->num, No))
{
flag = 1;
break;
}
}
if (flag == 0)
{
printf("查询不到次车次,请在核实后重新输入\n");
}
else
{
if (pTic[k].peo >= pTic[k].peomax)
{
printf("对不起,本次列车已无空位.\n");
}
else
{
printf("确定要购买本车票吗?(y/n)>");
getchar();
scanf("%c", &input);
if (input == 'y')
{
pTic[k].peo = pTic[k].peo + 1;
FILE* pWrite = fopen("ticket.txt", "w");
if (pWrite == NULL)//打开失败
{
printf("%s\n", strerror(errno));
}
else//打开成功
{
int i = 0;
for (i = 0; i < *no; i++)
{
fprintf(pWrite, "%s %s %s %s %d %d %d %s ", (pTic + i)->num, (pTic + i)->time1, (pTic + i)->name1, (pTic + i)->name2, (pTic + i)->time2, (pTic + i)->peomax, (pTic + i)->peo, (pTic + i)->rq);
}
fclose(pWrite);//关闭文件
pWrite = NULL;
printf("购票成功!\n");
}
}
}
}
}
2.4.8退票模块tuiTicket
1模块功能:通过输入退票车次号进行退票
2输入输出:
形式:void tuiTicket(Ticket* pTic, int* no)
归属:User
3模块代码:
void tuiTicket(Ticket* pTic, int* no)
{
int k;
char No[10];
char input;
bool flag = 0;
printf("请输入您要退购车票的车次号>");
scanf("%s", No);
for (k = 0; k < *no; k++)
{
if (!strcmp((pTic + k)->num, No))
{
flag = 1;
break;
}
}
if (flag == 0)
{
printf("查询不到次车次,请在核实后重新输入\n");
}
else
{
if (pTic[k].peo == 0)
{
printf("对不起,恁没有购买本列车车票.\n");
}
else
{
printf("确定要退购本车票吗?(y/n)>");
getchar();
scanf("%c", &input);
if (input == 'y')
{
pTic[k].peo = pTic[k].peo - 1;
FILE* pWrite = fopen("ticket.txt", "w");
if (pWrite == NULL)//打开失败
{
printf("%s\n", strerror(errno));
}
else//打开成功
{
int i = 0;
for (i = 0; i < *no; i++)
{
fprintf(pWrite, "%s %s %s %s %d %d %d %s ", (pTic + i)->num, (pTic + i)->time1, (pTic + i)->name1, (pTic + i)->name2, (pTic + i)->time2, (pTic + i)->peomax, (pTic + i)->peo, (pTic + i)->rq);
}
fclose(pWrite);//关闭文件
pWrite = NULL;
printf("退票成功!\n");
}
}
}
}
}
2.5Menu
模块代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int loginMenu()//登入选择菜单模块(管理员、用户)
{
int input;
printf(" 欢迎进入车票管理系统\n");
printf("1 以管理员的身份登录 2 以用户的身份登入\n");
printf("3 没有账户?立即注册 4 退出系统\n");
printf("请选择功能序号(1、2、3、4)>");
scanf("%d", &input);
return input;
}
int fanHuiMenu()//返回上一级菜单
{
char input;
printf("是否返回上一级(Y/N)>");
while (getchar() != '\n')//清空输入缓冲区
{
continue;
}
scanf("%c", &input);
if (input == 'Y')
{
return 0;
}
else
return 1;
}
int managerChoiceMenu1()//管理员选择一级菜单
{
int input;
printf(" 欢迎进入管理员操作端\n");
printf("1 增加车次 2 删除车次\n");
printf("3 修改车次信息 4 退出登录\n");
printf("请选择功能序号(1、2、3、4)>");
scanf("%d", &input);
return input;
}
int userChoiceMenu1()//用户选择一级菜单
{
int input;
printf(" 欢迎进入用户操作端\n");
printf("1 查询车票 2 购买车票\n");
printf("3 退票 4 退出登录\n");
printf("请选择功能序号(1、2、3、4)>");
scanf("%d", &input);
return input;
}
int modifyMenu()//修改信息菜单
{
int input;
printf(" 请输入要修改的信息类型\n");
printf("1 发车时间 2 始发站\n");
printf("3 终点站 4 最大载客量\n");
printf("5 订票人数 \n");
printf("请选择功能序号(1、2、3、4、5、6)>");
scanf("%d", &input);
return input;
}
int userChoiceMenu2()//用户查询菜单
{
int input;
printf(" 请选择查询的方式或内容\n");
printf("1 目的地查询 2 起点查询\n");
printf("3 列车信息查询\n");
printf("请选择功能序号(1、2、3)>");
scanf("%d", &input);
return input;
}
2.6Manager.h
#pragma once
#ifndef Manager_h
#define Manager_h
struct Manager {
char id[10];//用户名
char password[20];//密码
};
struct Ticket
{
char num[10]; //车次
char time1[10]; //发车时间
char name1[20]; //始发站
char name2[20]; //终点站
int time2; //行车时间
int peomax; //最大载客量
int peo; //已订票人数
char rq[20];//日期
};
void managerDenRu(Ticket* pTic,int* no);
void addCheCi(Ticket* pTic, int* no);
void delCheCi(Ticket* pTic, int* no);
void modifyXinXi(Ticket* pTic, int no);
#endif
2.7Menu.h
#pragma once
#ifndef Menu_h
#define Menu_h
int loginMenu();
int fanHuiMenu();
int managerChoiceMenu1();
int userChoiceMenu1();
int modifyMenu();
int userChoiceMenu2();
#endif
2.8System.h
#pragma once
#ifndef System_h
#define System_h
#include"User.h"
#include"Manager.h"
int duQuShuJu(Ticket* pTic);
int duQuUser(User* us);
#endif
2.9User.h
#pragma once
#ifndef User_h
#define User_h
#include"Manager.h"
struct User {
char id[10];//用户名
char password[20];//密码
};
void zhuCe(User* us, int* no);
void userDengRu(Ticket* pTic, int* no);
void chaXun(Ticket* pTic, int* no);
void chaXunMuDiDi(Ticket* pTic, int* no);
void chaXunQiDian(Ticket* pTic, int* no);
void chaXunCheCi(Ticket* pTic, int* no);
void maiTicket(Ticket* pTic, int* no);
void tuiTicket(Ticket* pTic, int* no);
#endif