❤️作者主页:微凉秋意
✅作者简介:后端领域优质创作者🏆,CSDN内容合伙人🏆,阿里云专家博主🏆
文章目录
- 一、案例需求描述
- 1.1、汽车信息模块
- 1.2、普通用户模块
- 1.3、管理员用户模块
- 二、案例分析
- 三、案例代码实现
- 3.1、汽车信息类及方法实现
- 3.2、普通用户类及方法实现
- 3.3、管理员用户类及方法实现
- 3.4、主函数调用情况
- 四、运行界面截图
之前写的停车场管理系统或者是通讯录管理系统都没有使用文件录入、保存数据,今天带来一个文件录入信息的C++版停车场管理系统。代码部分都会有详细注释,稍加思考都能够理解该程序的逻辑。
一、案例需求描述
停车场管理系统就是模拟停车场进行车辆管理的系统,该系统分为汽车信息模块,用户使用模块和管理员用户模块,各模块功能如下所示:
1.1、汽车信息模块
- 添加汽车信息:添加汽车属性。
- 删除汽车信息:输入停车场中存在的车牌号,删除汽车信息。
- 查找汽车信息:输入停车场存在的车牌号,显示汽车详细信息。
- 修改汽车信息:输入停车场内存在的车牌号,修改汽车属性信息。
- 停车时长统计:显示汽车在停车场中停留的时间和车辆总数。
- 停车场信息显示:显示停车场所有汽车的属性信息。
- 汽车信息保存:将汽车信息保存到本地文件中。
1.2、普通用户模块
可以查询、显示所有汽车信息及停车费信息,另外还包含停车时长统计与退出普通用户登录功能。由于是多次操作,因此需要有循环判断功能,这种情况多使用while
嵌套switch case
语句实现。
1.3、管理员用户模块
此模块具有普通用户模块的所有功能,此外还应有增、删、改的功能。
二、案例分析
通过案例描述我们得到了非常清晰的模块信息,因此在设计类时应该包含普通用户类、管理员用户类、汽车信息类。
大致思路:
- 在汽车信息类中实现基本功能并封装起来,以便后续调用。
- 在普通用户类中定义菜单功能,通过键入不同数字实现不同功能。
- 在管理员用户类中定义菜单功能,通过键入不同数字实现不同功能。
三、案例代码实现
这里我采用分文件编写的方式,建立user.h
、admin.h
、car.h
及对应的三个.cpp
文件和main.cpp
文件,在main里面循环调用user
和admin
的方法就能实现停车场管理系统。
3.1、汽车信息类及方法实现
car.h
#pragma once // 防止头文件被重复调用
#include<string>
#include<ctime>
using namespace std;
class Car {
private:
string carNum; // 汽车编号
string carType; // 汽车型号
string color; // 汽车颜色
time_t inTime; // 汽车停车时间点
public:
void addCar(); // 下面四行对应增删改查
void delCar();
void modCar();
void findCar();
void timeAmount(); // 计算停车时长并统计汽车总数
void showInfor(); // 显示车辆信息(读文件)
void saveInfor(); // 保存车辆信息(写文件)
};
car.cpp
#include"car.h"
#include<fstream> // 读写操作
#include<iostream>
#include<iomanip> // IO流控制头文件,类似C里的格式化输出
using namespace std;
void Car::addCar() {
time_t _time; // 定义时间变量,秒数,调用time()获取
while (1) {
AA: cout << "请输入车牌号:";
cin >> carNum;
// 判断文件中是否已存在相同车牌号
ifstream ifs("carData.txt", ios::in); // 读文件
if (ifs) {
char buf[1024];
string strs[20];
int index = 0; // 标识数组索引
while (!ifs.eof()) { // 读取文件直到末尾
ifs.getline(buf, 100); // 每次读取一行数据,放入buf数组 注:第二个参数为字符数,缓冲区尽量大,否则循环会异常结束
strs[index++] = buf[0]; // buf[0]为车牌号,存入strs数组,索引自增
}
// 遍历strs数组,auto 自动推导数据类型,这里等价于 string
for (auto& num : strs) {
// 判断输入车牌号是否与文件里重复
if (num == carNum) {
cout << "车牌号重复!" << endl;
goto AA; // 重复后重新输入车牌号
}
}
}
// 车牌号不重复继续加下来的输入
cout << "请输入车的种类:";
cin >> carType;
cout << "请出入车的颜色:";
cin >> color;
inTime = time(&_time); // 记录停车时间
// 保存新增车辆信息
saveInfor();
char ch;
cout << "\t是否继续?(y/n)"; // 判断是否继续输入,\t 制表符,通常八个空格
cin >> ch;
if (ch == 'n' || ch == 'N') {
break;
}
}
}
void Car::delCar() {
// 读文件
ifstream carData("carData.txt", ios::in);
// 创建文件写入流,缓冲文件
ofstream outData("tempCarData.txt", ios::out);
if (!outData || !carData) {
cout << "文件打开失败!" << endl;
return;
}
string carId, name, str;
bool flag = true;
cout << "请输入要删除的车牌号:";
cin >> carId;
// 读取文件第一个字段(车牌号) >> 遇空格结束读取
while (carData >> name) {
getline(carData,str); // 将该行数据读取到 str
// 如果相同,输出要删除的车辆信息:颜色,型号,停车时间
if (name == carId) {
cout << "要删除的车辆信息:" << endl << str << endl;
flag = false;
break;
}
// 如果不相同,将车辆信息写入到temp,否则舍弃该行
outData << name << " " << str << endl;
}
if (flag) cout << "该车牌号不存在" << endl;
else {
while (getline(carData, str)) { // 继续按行读取,此时第一行
outData << str << endl; // 写入到temp
}
carData.close();
outData.close();
// 读取 temp,写入 carData
ifstream in("tempCarData.txt", ios::in);
ofstream out("carData.txt", ios::out);
if (!in || !out) {
cout << "文件读取失败!" << endl;
return;
}
else {
while (getline(in, str)) { // 按行读取,写入
out << str << endl;
}
}
in.close();
out.close();
}
}
void Car::modCar() {
string chepai1, chepai2, str;
time_t time1;
int i = 1;
cout << "请输入你要修改的车辆的车牌号" << endl;
cin >> chepai1;
ifstream indata("carData.txt", ios::in);
ofstream outdata("tempCarData.txt", ios::out);
if (!indata || !outdata)
{
cerr << "文件打开错误" << endl;
exit(1);
}
while (indata >> chepai2)
{
indata >> carType >> color >> inTime; // 读取该行剩余元素
if (chepai1 == chepai2)
{
i = 0;
cout << "已找到所要修改的车辆" << endl;
cout << "修改后的车牌号" << endl;
cin >> carNum;
cout << "修改后的车辆型号" << endl;
cin >> carType;
cout << "修改后的车辆颜色" << endl;
cin >> color;
inTime = time(&time1);
// 写入carData.txt
outdata << carNum << " " << carType << " " << color << " " << inTime << endl;
break;
}
// 车牌号不同,将车辆信息存到temp
outdata << chepai2 << " " << carType << " " << color << " " << inTime << endl;
}
if (i) {
cout << "停车场中没有找到要修改的车辆" << endl;
}
outdata.close();
indata.close();
ifstream in("tempCarData.txt", ios::in);
ofstream out("carData.txt", ios::out);
if (!in || !out)
{
cout << "文件打开错误" << endl;
exit(1);
}
while (getline(in, str))
{
out << str << endl;
}
in.close();
out.close();
}
void Car::findCar() {
ifstream carData("carData.txt", ios::in);
if (!carData)
{
cout << "文件打开失败" << endl;
return;
}
else {
string carId;
time_t _time, t1;
bool flag = true;
cout << "请输入要查找的车牌号" << endl;
cin >> carId;
while (carData >> carNum) // 读取车牌号
{
carData >> carType >> color >> inTime;
t1 = time(&_time); // 获取系统当前时间
if (carId == carNum)
{
flag = false;
break;
}
}
if (flag) {
cout << "未找到该车辆信息!" << endl;
}
else {
cout << "车牌号" << carNum <<" "<<"车的型号:" << carType <<" " <<
" 车的颜色:" << color << " "<<"停车时长:" << (t1 - inTime) << "秒"
<<" "<< "停车费 " << (t1 - inTime) * 0.05 << "元" << endl;
}
carData.close();
}
}
void Car::timeAmount() {
time_t it, time1;
int c1 = 0, c2 = 0;
ifstream indata("carData.txt", ios::in);
if (!indata)
{
cerr << "文件打开失败" << endl;
exit(1);
}
while (indata >> carNum)
{
indata >> carType >> color >> inTime;
it = time(&time1);
if ((it - inTime) / (60 * 60 * 24) >= 24)
{
c1++;
}
else c2++;
}
cout << "车辆总数是:" << c1 + c2 << endl;
cout << "其中停放超过24小时的有" << c1 << "辆" << endl;
cout << "其中停放不超过24小时的有" << c2 << "辆" << endl;
indata.close();
}
void Car::showInfor() {
int i = 1;
string chepai;
time_t it, time1;
ifstream indata("carData.txt", ios::in);
if (!indata)
{
cerr << "文件打开错误" << endl;
exit(1);
}
cout << "停车场中所有汽车信息如下所示:" << endl;
cout << "-----------------------------" << endl;
while (indata >> chepai)
{
indata >> carType >> color >> inTime;
it = time(&time1);
cout << "第" << i << "辆车信息如下" << endl;
cout << "车牌号" << chepai << " 车的型号:" << carType << " 车的颜色:" << color
<< " 停车时间" << (it - inTime) << "秒" <<
" 停车费 " << (it - inTime) * 0.05 << "元" << endl;
i++;
}
indata.close();
}
void Car::saveInfor() {
ofstream outData("carData.txt", ios::app); // app 追加方式写文件,即在文件末尾添加
if (!outData) {
cout << "文件打开失败!" << endl;
return;
}
else {
// 将新增车辆信息写入carData
outData << carNum << " " << carType << " " << color << " " << inTime << endl;
}
outData.close();
}
3.2、普通用户类及方法实现
user.h
#pragma once
#include<string>
using namespace std;
// 普通用户类,只能查看、统计、显示车辆,无法实现增删改
class User {
public:
void checkCar(); // 普通用户登录菜单
};
user.cpp
#include<iostream>
#include<Windows.h>
#include"user.h"
#include"car.h"
using namespace std;
void User::checkCar() {
Car car;
while (1) {
system("cls"); // 清空屏幕
cout << "1.显示车辆状况" << endl;
cout << "2.查询车辆信息" << endl;
cout << "3.统计车辆" << endl;
cout << "4.退出普通用户" << endl;
int c;
cout << "输入要执行的操作:";
cin >> c;
switch (c) {
case 1: car.showInfor(); break;
case 2: car.findCar(); break;
case 3: car.timeAmount(); break;
case 4: return;
default: cout << "请输入正确的操作" << endl;
}
system("pause");
}
}
3.3、管理员用户类及方法实现
admin.h
#pragma once // 避免同一个头文件被包含多次
#include<string>
#include"user.h"
using namespace std;
// 管理员类,公有继承普通用户类,可以添加,修改,删除
class Admin:public User {
public:
void Manager(); // 显示管理员登录的菜单
};
admin.cpp
#include"admin.h"
#include"car.h"
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
void Admin::Manager() {
Car car;
while (1) {
system("cls"); // 清空屏幕
cout << "1.增加车辆" << endl;
cout << "2.显示所有车辆信息" << endl;
cout << "3.查询" << endl;
cout << "4.修改" << endl;
cout << "5.删除" << endl;
cout << "6.统计" << endl;
cout << "7.退出管理用户" << endl;
int choice;
cout << "请输入要执行的操作:";
cin >> choice;
switch (choice) {
case 1: car.addCar(); break;
case 2: car.showInfor(); break;
case 3: car.findCar(); break;
case 4: car.modCar(); break;
case 5: car.delCar(); break;
case 6: car.timeAmount(); break;
case 7: return;
default: cout << "输入错误!" << endl;
}
system("pause");
}
}
3.4、主函数调用情况
#include"user.h"
#include"admin.h"
#include<iostream>
using namespace std;
int main() {
User user; // 普通用户对象
Admin admin; // 管理员对象
int choice;
while (1) {
system("cls");
cout << "1.普通用户登录" << endl;
cout << "2.管理员登录" << endl;
cout << "3.退出系统" << endl;
cout << "请输入要执行的操作:" << endl;
cin >> choice;
switch (choice) {
case 1: user.checkCar(); break;
case 2: admin.Manager(); break;
case 3: exit(0); // 退出系统
default: cout << "请输入正确的操作" << endl;
}
system("pause");
}
return 0;
}
四、运行界面截图
剩下的就不展示了。。。
这个停车场管理系统最需要掌握的便是程序设计的思想以及文件操作,像分文件编写或是文件操作我也写过文章总结,就在《C++面向对象部分》专栏里,感兴趣的朋友可以订阅学习。