开发环境

使用 Visual Studio 2019\text{Visual Studio 2019} 开发,程序直接在 cmd\text{cmd} 界面运行。

题目

应用场景

一车站每天有 nn 个发车班次,每个班次都有一班次号 1,2,3n1,2,3\cdots 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++}设计一系统,能提供下列服务:
(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)将类 viewCbus 分别定义在 view.hCbus.h 中。
(2)将类 viewCbus 的函数分别定义在 view.cppCbus.cpp 中。
(3)将主函数写在 主控.cpp 中。

功能模块图

主函数

主函数.png

查看班车信息

查看班车信息.png

录入班车信息

录入班次信息.png

清空班车信息

清空班次信息.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()

成员函数伪代码
输出信息到文件
1
2
3
4
5
6
7
void Cbus::get_file_out()
{
定义文件输出流;
open(ios::out);
将bus中的信息输出至文件;
close;
}
从文件输入信息
1
2
3
4
5
6
7
void Cbus::get_file_in()
{
定义文件输出流;
open(ios::in || ios::_Nocreate);
将文件信息输入至bus;
close;
}
显示所有班次信息
1
2
3
4
5
void Cbus::print_all_information()
{
get_file_in();
将bus信息输出至屏幕;
}
添加班次信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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;
}
清空班次信息
1
2
3
4
5
6
void Cbus::clear_all_information()
{
定义文件输出流;
Open(ios::out);
Close;
}

class view

功能

用来打印初始化界面,利用光标移动在工作台不同位置打印字符,字符色彩由编码决定。

成员函数

public 部分

打印初始化界面 void oninit()

private 部分

打印工作台的边缘方框 void edge();光标移动 void goto_xy(int, int)

成员函数伪代码

光标移动
1
2
3
4
5
6
void view::goto_xy(int x, int y)
{
定义光标 HANDLE HOut;
定义坐标 {x,y};
设置位置goto (x,y);
}
打印工作台边缘方框
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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;
}
}
}
打印初始化界面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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 << '.';
}
清屏;
}

主函数

功能

用来打印主菜单,并跳转到各种功能的界面,操作完成后返回主菜单。

伪代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#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

1
2
3
4
5
6
7
8
9
10
11
12
#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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#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");