开发环境
使用 Visual Studio 2019 \text{Visual Studio 2019} Visual Studio 2019 开发,程序直接在 cmd \text{cmd} cmd 界面运行。
题目
应用场景
一车站每天有
n
n
n 个发车班次,每个班次都有一班次号
1
,
2
,
3
⋯
n
1,2,3\cdots n
1,2,3⋯n,固定发车时间,固定的路线(起始站、终点站),大致的行车时间、固定的额定载客量。
某一天得车次如下表所述。
班次 | 发车时间 | 起点站 | 终点站 | 行车时间(小时) | 额定载量(人) | 已订票人数(人) |
---|---|---|---|---|---|---|
1 | 8:00 | 郫县 | 广汉 | 2 | 45 | 30 |
2 | 6:30 | 郫县 | 成都 | 0.5 | 40 | 40 |
3 | 7:00 | 郫县 | 成都 | 0.5 | 40 | 20 |
4 | 10:00 | 郫县 | 成都 | 0.5 | 40 | 2 |
功能要求
用
C/C++
\text{C/C++}
C/C++设计一系统,能提供下列服务:
(1)录入班次信息(信息用文件保存),可不定时地增加班次数据;
(2)浏览班次信息,即显示所有班次当前状况。
视频演示
车票管理系统(BV1Qp4y1i76Q)演示,有录入班次信息、浏览班次信息、删除班次信息等功能。
设计思路
程序框架和代码实现
(1)设计一个班车的类 class Cbus
。类中包括班次的数据内容和实现功能的函数。
(2)利用文本文件来保存班次的数据,因此要设计读写文件的函数 void get_file_in()
和 void get_file_out()
。
(3)设计函数来实现服务,录入班次信息的函数 void input_information()
,显示所有班次当前状况的函数void print_all_information()
,为方便整理数据,还特别设计了清空所有信息的函数 void clear_all_information()
。
(4)类的 public
部分写入实现服务的函数作为对外接口,private
部分写入数据和文件读写的函数。
(5)班次有若干信息组成,班次的信息包括:班次、发车时间、起点站、终点站、行车时间、额定载量、已订票人数。因此可将车票定义为结构体 struct Bus
。
(6)需要不定时地输入班次信息,因此定义 Bus
类型的动态数组 vector<Bus>bus
,写入类中。
(7)主菜单提供功能选项,通过if语句实现功能的选择。
(8)主函数写入显示功能菜单的函数 void print_desktop()
,供用户选择操作。
(9)读取文件信息的实现:① 以输入方式 ios::in||ios::_Nocreat
打开文件。② 定义文件输入流。③ 用循环方式将文件输入至动态数组bus中,直至读取不到文件中的信息。④ 关闭文件。
(10)输出信息到文件的实现:①以输出方式 ios::out
打开文件。② 定义文件输出流。③ 定义迭代器it,用循环方式将动态数组 bus
中的数据输出至文件中,直至 it==bus.end()
。④ 关闭文件。
(11)录入班次的信息的实现:① 调用 get_file_in()
。② 定义 Bus
类型的变量 t
。③ 依次读取 t
的成员④ 利用函数 bus.push_back(Bus)
将一组数据存入动态数组。⑤ 调用 get_file_out()
。
(12)浏览班次信息的实现:① 调用 get_file_in()
。② 利用迭代器将 bus
中的数据输出。
(13)清空信息的实现:① 定义文件输出流。② 以 ios::out
方式打开文件。③ 关闭文件。
(14)功能完善:① 录入信息时,先询问需要录入几个班次的信息,当信息录入完成时,再次询问是否需要继续录入信息。② 如果输入错误的数据,程序应当提示错误信息,可利用 string
类型的比较实现。③ 每步操作后,都要提供返回主菜单继续执行程序或者结束程序的操作。④ 每执行完一个功能,进行一次清屏操作,利用函数 system(“cls”)
实现。
界面的设计
(1)旨在用后端程序显示一些类似前端的界面。
(2)定义函数 SetPos(short,short)
,实现光标的跳动。
(3)利用红色的特定编码,显示红色的符号。
(4)初始化界面的实现:① 打印边框。② 调用 SetPos(short,short)
,将光标移动到合适位置。③ 利用函数 Sleep(int)
实现进度条缓慢移动的效果。
(4)定义初始化界面的类 Class view
,内含打印界面的函数。
(5)执行操作时,为了美观,在界面上方和下方打印出红色的符号
#
\color{Red}\#
#。
提高代码逻辑
(1)将类 view
和 Cbus
分别定义在 view.h
和 Cbus.h
中。
(2)将类 view
和 Cbus
的函数分别定义在 view.cpp
和 Cbus.cpp
中。
(3)将主函数写在 主控.cpp
中。
功能模块图
主函数
查看班车信息
![查看班车信息.png](https://i-blog.csdnimg.cn/blog_migrate/f9b100f04843bc87dd2232cf8ebb7259.png)
录入班车信息
清空班车信息
![清空班次信息.png](https://i-blog.csdnimg.cn/blog_migrate/078a8ece512ad5f461d2820f9cd00af7.png)
程序设计
结构体 struct Bus
结构体内定义如下数据:班次 string shift
;发车时间 string departure_time
;始发站 string departure_station
;终点站 string terminus
;行车时间 string travel_time
;核载人数 string rated_load
;已定票人数 string booked_number
。
由于要求实现功能并不需要对发车时间、人数、行车时间等数据进行加减、比较大小等操作,因此所有数据类型都设定为 string
。
类 class Cbus
数据
private: vector<Bus>bus
成员函数
public 部分
输出所有班次信息 void print_all_information()
;输入信息 void input_information()
;清空信息 void clear_all_information()
。
private 部分
输出信息到文件 void get_file_out()
;读取文件信息 void get_file_in()
。
成员函数伪代码
输出信息到文件
void Cbus::get_file_out()
{
定义文件输出流;
open(ios::out);
将bus中的信息输出至文件;
close;
}
从文件输入信息
void Cbus::get_file_in()
{
定义文件输出流;
open(ios::in || ios::_Nocreate);
将文件信息输入至bus;
close;
}
显示所有班次信息
void Cbus::print_all_information()
{
get_file_in();
将bus信息输出至屏幕;
}
添加班次信息
void Cbus::input_information()
{
get_file_in();
int n
while(cin>>n)
{
Bus t;
while(n--)
{
cin>>t的元素;
Bus.push_back(t);
}
string sign;
While(1)
{
cin>>sign;
if(sign=="1" or "2")break;
else continue;
}
if(sign=”1”)continue;
else if(sign=”2”)break;
}
get_file_out;
}
清空班次信息
void Cbus::clear_all_information()
{
定义文件输出流;
Open(ios::out);
Close;
}
类 class view
功能
用来打印初始化界面,利用光标移动在工作台不同位置打印字符,字符色彩由编码决定。
成员函数
public 部分
打印初始化界面 void oninit()
。
private 部分
打印工作台的边缘方框 void edge()
;光标移动 void goto_xy(int, int)
。
成员函数伪代码
光标移动
void view::goto_xy(int x, int y)
{
定义光标 HANDLE HOut;
定义坐标 {x,y};
设置位置goto (x,y);
}
打印工作台边缘方框
void view::edge()
{
int x1 = 0, y1 = 0, i, j;
for (i 0~ 30)
{
y1 = i;
goto(x1, y1);
if (i == 0 , 29)
{
for (j 1~ 60)
打印蓝色的■;
}
else
{
打印蓝色的■;
x1 = 118;
goto(x1, y1);
打印蓝色的■;
x1 = 0;
}
}
}
打印初始化界面
void view::oninit()
{
edge();
goto(44, 3);
欢迎使用车票管理系统;
goto(48,5);
系统初始化中;
goto(38, 15);
Sleep(1000);
正在进入系统;
Sleep(800);
goto(38, 18);
Sleep(700);
for (i~20)
{
Sleep(500);
打印绿色的>;
}
goto(38, 20);
即将进入系统;
Sleep(2000);
for (i1~10)
{
if (i == 2,3,4,5,6)Sleep(350);
else Sleep(200);
cout << '.';
}
清屏;
}
主函数
功能
用来打印主菜单,并跳转到各种功能的界面,操作完成后返回主菜单。
伪代码
int main()
{
view p;
p.oninit();
print_desktop();
Cbus f;
string choice;
while (cin >> choice)
{
if (choice =="1")
{
清屏;
f.print_all_information();
print_desktop();
}
else if (choice == "2")
{
清屏;
f.input_information();
print_desktop();
}
else if (choice == "3")
{
清屏;
f.clear_all_information();
print_desktop();
}
else if (choice == "4")
{
清屏;
exit;
}
else
{
提醒error;
}
}
return 0;
}
void print_desktop()
{
for (j 1~120)
打印红色的#;
打印主菜单
for (j 1~120)
打印红的的#;
}
程序代码
Cbus.h
#pragma once
#include<vector>
#include<iostream>
#include<string>
#include<cstdlib>
#include<cstdio>
#include<fstream>
using namespace std;
struct Bus
{
string shift;//班次
string departure_time;//发车时间
string departure_station;//始发站
string terminus;//终点站
string travel_time;//行车时间
string rated_load;//核载人数
string booked_number;//已订票人数
};
class Cbus
{
public:
void print_all_information();//输出所有班次信息
void input_information();//输入信息
void clear_all_information();//清空信息
private:
vector<Bus>bus;
void get_file_out();//输出信息到文件
void get_file_in();//读取文件信息
};
Cbus.cpp
#include "Cbus.h"
void Cbus::get_file_in()
{
vector <Bus>().swap(bus);//清空bus
ifstream infile;//定义文件输入流
infile.open("班车信息.txt", ios::in || ios::_Nocreate);
if (!infile)//检验文件是否打开成功
{
cerr << "打开文件错误!";
cout<< endl;
exit(0);
}
Bus t;
//读取文件所有数据
while
(
infile >> t.shift&&
infile>> t.departure_time &&
infile>> t.departure_station &&
infile>> t.terminus&&
infile >> t.travel_time &&
infile>> t.rated_load &&
infile>> t.booked_number
)
{
bus.push_back(t);
}
infile.close();
}
void Cbus::get_file_out()
{
ofstream outfile;//定义文件输出流
outfile.open("班车信息.txt", ios::out);
if (!outfile)
{
cerr << "open error!" << endl;
exit(0);
}
vector<Bus>::iterator it;//定义迭代器
for ( it = bus.begin(); it != bus.end(); it++)
{
outfile << (*it).shift << ' ';
outfile << (*it).departure_time << ' ';
outfile << (*it).departure_station << ' ';
outfile << (*it).terminus << ' ';
outfile << (*it).travel_time << ' ';
outfile << (*it).rated_load << ' ';
outfile<< (*it).booked_number << endl;
}
outfile.close();
}
void Cbus::print_all_information()
{
get_file_in();
for (int j = 1; j <= 120; j++)//打印红色边框
printf("\033[31m#\033[0m");
if (!bus.empty())//等价于文件中有信息
{
//打印表格
cout << endl << endl<<" ";
cout << " 班次";
cout << " 发车时间";
cout << " 起点站";
cout << " 终点站";
cout << " 行车时间";
cout << " 额定载量";
cout<<" 已定票人数" << endl;
vector<Bus>::iterator it;
for ( it = bus.begin(); it != bus.end(); it++)
{
cout << " "<< " ";
cout << (*it).shift << " ";
cout << (*it).departure_time << " ";
cout << (*it).departure_station << " ";
cout << (*it).terminus << " ";
cout << (*it).travel_time << " ";
cout << (*it).rated_load << " ";
cout<< (*it).booked_number << endl;
}
cout << endl << endl;
}
else
{
cout << endl<<endl;
cout << " ";
cout<< "没有班车信息!" << endl << endl;
}
for (int j = 1; j <= 120; j++)
printf("\033[31m#\033[0m");
string sign;
//打印功能选项
cout << endl;
cout<< " ";
cout << "请选择功能:"<< endl;
cout << " ";
cout << "【1】结束程序" << endl;
cout << " ";
cout<< "【2】返回桌面" << endl;
while (cin >> sign)//检验代码段,若输出错误,一直循环读取sign
{
if (sign == "1" || sign == "2")break;
else
{
cerr << "输入错误!";
cout << endl << "请重新输入:";
continue;
}
}
if (sign == "1")exit(0);
else if (sign =="2")system("cls");
}
void Cbus::input_information()
{
get_file_in();
Bus t;
string sign;
while (1)
{
for (int j = 1; j <= 120; j++)
printf("\033[31m#\033[0m");
int n;
cout << " ";
cout<< "请输入录入班车的数量:";
cin >> n;
for(int i=1;i<=n;i++)//录入n组信息
{
system("cls");
for (int j = 1; j <= 120; j++)
printf("\033[31m#\033[0m");
cout << " ";
cout<< "请输入第" << i << "辆车的信息" << endl;
cout << " ";
cout<< "请输入班次:";
cin >> t.shift;
cout << " ";
cout<< "请输入发车时间:";
cin >> t.departure_time;
cout << " ";
cout<< "请输入起点站:";
cin >> t.departure_station;
cout << " ";
cout<< "请输入终点站:";
cin >> t.terminus;
cout << " ";
cout<< "请输入行车时间:";
cin >> t.travel_time;
cout << " ";
cout<< "请输入额定载量:";
cin >> t.rated_load;
cout << " ";
cout<< "请输入已定票人数:";
cin >> t.booked_number;
bus.push_back(t);
}
//询问是否继续录入
cout << " ";
cout << "录入信息完成,是否继续录入?" << endl;
cout << " ";
cout << "【1】是" << endl;
cout << " ";
cout<< "【2】否" << endl;
while (cin >> sign)
{
if (sign =="1" || sign == "2")break;
else
{
cerr << "输入错误!";
cout << endl << "请重新输入:";
continue;
}
}
if (sign == "1")
{
system("cls");
continue;
}
else if (sign == "2")break;
}
//录入结束后输出信息到文件
get_file_out();
for (int j = 1; j <= 120; j++)
printf("\033[31m#\033[0m");
cout << " ";
cout<< "请选择功能:" << endl;
cout << " ";
cout << "【1】结束程序" << endl;
cout << " ";
cout<< "【2】返回桌面" << endl;
while (cin >> sign)
{
if (sign == "1" || sign == "2")break;
else
{
cerr << "输入错误!";
cout << endl << "请重新输入:";
continue;
}
}
if (sign == "1")
{
system("cls");
exit(0);
}
else if (sign == "2")system("cls");
}
void Cbus::clear_all_information()
{
ofstream outfile;
outfile.open("班车信息.txt");
if (!outfile)
{
cerr << "打开文件错误!" << endl;
exit(0);
}
outfile.close();
for (int j = 1; j <= 120; j++)
printf("\033[31m#\033[0m");
cout << endl<<endl;
cout << " ";
cout<< "已清空所有信息!" << endl << endl;
string sign;
for (int j = 1; j <= 120; j++)
printf("\033[31m#\033[0m");
cout << endl;
cout << " ";
cout << "请选择功能:" << endl;
cout << " ";
cout << "【1】结束程序" << endl;
cout << " ";
cout<< "【2】返回桌面" << endl;
while (cin >> sign)
{
if (sign == "1" || sign == "2")break;
else
{
cerr << "输入错误!";
cout << endl << "请重新输入:";
continue;
}
}
if (sign == "1")exit(0);
else if (sign == "2")system("cls");
}
view.h
#pragma once
#include<ctime>
#include<Windows.h>
#include<cstdlib>
#include<cstdio>
class view
{
public:
void oninit();//打印初始化界面
void edge();//打印边框
static void goto_xy(int x, int y);//控制光标移动
};
view.cpp
#include "view.h"
#include<iostream>
#include<cstdio>
using namespace std;
void view::goto_xy(int x, int y)
{
HANDLE HOut = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos = { x, y };//光标位置x,y
SetConsoleCursorPosition(HOut, pos);//设置光标位置
}
void view::edge()
{
int x1 = 0, y1 = 0, i, j;
for (i = 0; i < 30; i++)//逐行打印游戏边框
{
y1 = i;
goto_xy(x1, y1);//将光标移动到i行起始处
if (i == 0 || i == 29)//在第1,30行打印上下边框
{
for (j = 1; j <= 60; j++)
printf("\033[36m■\033[0m");
}
else//其他行只打印左右边框
{
printf("\033[36m■\033[0m");
x1 = 118;
goto_xy(x1, y1);
printf("\033[36m■\033[0m");
x1 = 0;
}
}
}
void view::oninit()
{
edge();
goto_xy(44, 3);
cout << " 欢迎使用车票管理系统";
goto_xy(48,5);
cout << " 系统初始化中";
goto_xy(38, 15);
Sleep(1000);
cout << "正在进入系统";
Sleep(800);
goto_xy(38, 18);
Sleep(700);
for (int i = 0; i < 20; i++)
{
Sleep(500);
cout << "\033[1;40;32m>\033[0m";
}
goto_xy(38, 20);
cout << "即将进入系统";
Sleep(2000);
for (int i = 1; i <= 10; i++)
{
if (i == 2 || i == 3 || i == 4 || i == 5 || i == 6)Sleep(350);
else Sleep(200);
cout << '.';
}
system("cls");
}
主控.cpp
#include"Cbus.h"
#include"view.h"
void print_desktop();//打印主菜单的函数
int main()
{
view p;//定义view类型的对象
p.oninit();
print_desktop();
Cbus f;//定义Cbus类型的对象
string choice;
while (cin >> choice)//用循环实现连续输入
{
if (choice =="1")
{
system("cls");
f.print_all_information();
print_desktop();
}
else if (choice == "2")
{
system("cls");
f.input_information();
print_desktop();
}
else if (choice == "3")
{
system("cls");
f.clear_all_information();
print_desktop();
}
else if (choice == "4")
{
system("cls");
exit(0);
}
else
{
cerr << "input error!";
cout << endl << "请重新输入!"<<endl;
}
}
return 0;
}
void print_desktop()
{
for (int j = 1; j <=120; j++)
printf("\033[31m#\033[0m");
printf
(
"\n"
"\n"
"\n"
" "
"车票管理系统 \n"
"\n"
"\n"
"\n"
" "
"请选择功能\n"
" "
"【1】查看所有班车信息\n"
" "
"【2】添加班车信息\n"
" "
"【3】清空所有班车信息\n"
" "
"【4】退出系统\n"
"\n"
"\n"
);
for (int j = 1; j <= 120; j++)//打印边框
printf("\033[31m#\033[0m");