停车场管理系统文件录入(C++版)

news2024/11/16 21:40:33

❤️作者主页:微凉秋意
✅作者简介:后端领域优质创作者🏆,CSDN内容合伙人🏆,阿里云专家博主🏆

文章目录

  • 一、案例需求描述
    • 1.1、汽车信息模块
    • 1.2、普通用户模块
    • 1.3、管理员用户模块
  • 二、案例分析
  • 三、案例代码实现
    • 3.1、汽车信息类及方法实现
    • 3.2、普通用户类及方法实现
    • 3.3、管理员用户类及方法实现
    • 3.4、主函数调用情况
  • 四、运行界面截图


之前写的停车场管理系统或者是通讯录管理系统都没有使用文件录入、保存数据,今天带来一个文件录入信息的C++版停车场管理系统。代码部分都会有详细注释,稍加思考都能够理解该程序的逻辑。

一、案例需求描述

  停车场管理系统就是模拟停车场进行车辆管理的系统,该系统分为汽车信息模块,用户使用模块和管理员用户模块,各模块功能如下所示:

1.1、汽车信息模块

  1. 添加汽车信息:添加汽车属性。
  2. 删除汽车信息:输入停车场中存在的车牌号,删除汽车信息。
  3. 查找汽车信息:输入停车场存在的车牌号,显示汽车详细信息。
  4. 修改汽车信息:输入停车场内存在的车牌号,修改汽车属性信息。
  5. 停车时长统计:显示汽车在停车场中停留的时间和车辆总数。
  6. 停车场信息显示:显示停车场所有汽车的属性信息。
  7. 汽车信息保存:将汽车信息保存到本地文件中。

1.2、普通用户模块

  可以查询、显示所有汽车信息及停车费信息,另外还包含停车时长统计与退出普通用户登录功能。由于是多次操作,因此需要有循环判断功能,这种情况多使用while嵌套switch case语句实现。

1.3、管理员用户模块

  此模块具有普通用户模块的所有功能,此外还应有增、删、改的功能。

二、案例分析

  通过案例描述我们得到了非常清晰的模块信息,因此在设计类时应该包含普通用户类、管理员用户类、汽车信息类。

大致思路:

  1. 在汽车信息类中实现基本功能并封装起来,以便后续调用。
  2. 在普通用户类中定义菜单功能,通过键入不同数字实现不同功能。
  3. 在管理员用户类中定义菜单功能,通过键入不同数字实现不同功能。

三、案例代码实现

  这里我采用分文件编写的方式,建立user.hadmin.hcar.h及对应的三个.cpp文件和main.cpp文件,在main里面循环调用useradmin的方法就能实现停车场管理系统。

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++面向对象部分》专栏里,感兴趣的朋友可以订阅学习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/419937.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql:使用终端操作数据库

登录进入终端&#xff1a; mysql -u root -p 展示数据库 SHOW DATABASES; 创建数据库&#xff1a; CREATE DATABASE IF NOT EXISTS RUNOOB_TEST DEFAULT CHARSET utf8 COLLATE utf8_general_ci; 1. 如果数据库不存在则创建&#xff0c;存在则不创建。 2. 创建RUNOOB_TEST数据库…

ElasticSearch安装、启动、操作及概念简介

ElasticSearch快速入门 文件链接&#xff1a;https://pan.baidu.com/s/15kJtcHY-RAY3wzpJZIn4-w?pwd0k5a 提取码&#xff1a;0k5a 有些软件对于安装路径有一定的要求&#xff0c;例如&#xff1a;路径中不能有空格&#xff0c;不能有中文&#xff0c;不能有特殊符号&#xf…

JUC并发编程之ReentrantLock

1. 非公平锁实现原理 加锁解锁流程 构造器默认实现的是非公平锁 public ReentrantLock() {sync new NonfairSync();}NonfairSync 继承 Sync&#xff0c; Sync 继承 AbstractQueuedSynchronizer 没有竞争时 第一个竞争出现时 Thread-1 执行了 CAS 尝试将state 由 0 改为 1&…

Stable Diffusion免费(三个月)通过阿里云轻松部署服务

温馨提示&#xff1a;划重点&#xff0c;活动入口在这里喔&#xff0c;不要迷路了。 其实我就在AIGC_有没有一种可能&#xff0c;其实你早就在AIGC了&#xff1f;阿里云邀请你&#xff0c;体验一把AIGC级的毕加索、达芬奇、梵高等大师作画的快感。阿里云将提供免费云产品资源&…

如何使用evosuite为指定被测方法生成测试用例

目录 省流版本 准备工作 环境 evosuite获取 检验环境 参数解释 怎样表示被测方法 怎样指向被测类 其他参数 参考 省流版本 java -jar .\target\depd\evosuite-1.1.0.jar -generateTests -Dtarget_method"isLenient()Z" -class com.google.gson.stream.…

Midjourney教程(二)——Prompt基本结构

Midjourney教程——Prompt基本结构 Basic Prompt 基础版本的prompt仅仅包含图片的描述&#xff0c;能够满足普通的需求&#xff0c;如下图所示 Advanced Prompt 高级版本的prompt主要包含三个部分&#xff0c;如下图所示 Image Prompts(可选) prompt第一部分是Image&#x…

TCP/IP协议详解

一.引言TCP/IP 是 TCP 和 IP 两种协议群的统称&#xff0c;具体来说&#xff0c;IP 或 ICMP、TCP 或 UDP、TELNET 或 FTP、以及 HTTP 等都属于 TCP/IP 协议二.计算机网络体系结构分层计算机网络体系结构分层计算机网络体系结构分层不难看出&#xff0c;TCP/IP 与 OSI 在分层模块…

【C语言】迷宫问题

【C语言】迷宫问题一. 题目描述二. 思想2.1 算法---回溯算法2.2 思路分析图解三. 代码实现3.1 二维数组的实现3.2 上下左右四个方向的判断3.4 用栈记录坐标的实现3.5 完整代码四. 总结一. 题目描述 牛客网链接&#xff1a;https://www.nowcoder.com/questionTerminal/cf2490605…

STM32看门狗

目录 独立看门狗 IWDG 什么是看门狗&#xff1f; 独立看门狗本质 独立看门狗框图 独立看门狗时钟 分频系数算法&#xff1a; ​编辑 重装载寄存器 键寄存器 溢出时间计算公式 独立看门狗实验 需求&#xff1a; 硬件接线&#xff1a; 溢出时间计算&#xff1…

macOS设置环境变量和别名

因为我的mac所用shell是bash&#xff0c;所以本文中涉及的环境变量和别名配置均在~/.zshrc文件中,且在每次配置完成后&#xff0c;需要执行source ~/.zshrc命令使配置文件生效 环境变量 通过配置环境变量&#xff0c;我们可以将某个路径暴露到全局&#xff0c;这样可以在全局…

周总结(第一周)

3月份3个星期 *** 三个星代表不会 ** 再做 * 加强 题目1-完全二叉树(记忆) 考察数据结构 完全二叉树的深度deplog2(N1)1 完全二叉树节点的深度depiceil(log2(i1))向上舍入 完全二叉树的层次遍历&#xff0c;遍历每层的二叉树计算基础每层的总和&#xff0c;然后找出最大的和…

Talk预告 | 新加坡国立大学郑奘巍 AAAI‘23 杰出论文:大批量学习算法加速推荐系统训练

本期为TechBeat人工智能社区第486期线上Talk&#xff01; 北京时间3月30日(周四)20:00&#xff0c;新加坡国立大学二年级博士生——郑奘巍的Talk将准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “大批量学习算法加速推荐系统训练”&#xff0c;届时将分…

Kubernetes 多集群网络方案系列 2 -- Submariner 监控

Submariner 是一个用于连接 Kubernetes 集群的跨集群网络解决方案&#xff0c;可以实现集群之间的服务发现、网络通信等功能。 Prometheus 是一个开源的监控和告警系统&#xff0c;专门用于收集、存储和查询各种应用、系统和基础设施的实时指标数据。Prometheus 具备多维数据模…

Java开发 - MySQL主从复制初体验

前言 前面已经学到了很多知识&#xff0c;大部分也都是偏向于应用方面&#xff0c;在应用实战这条路上&#xff0c;博主一直觉得只有实战才是学习中最快的方式。今天带来主从复制给大家&#xff0c;在刚刚开始动手写的时候&#xff0c;才想到似乎忽略了一些重要的东西&#xf…

面试篇-揭开Spring Bean加载的神秘面纱

SpringBean加载完整过程 启动spring容器&#xff08;创建beanfactory&#xff09;->加载配置(注解、xml)->实例化bean(执行构造方法)->注入依赖->初始化bean&#xff08;设置属性值&#xff09;->使用->销毁 解析和读取 XML 配置文件或注解配置类&#xff0…

Linux嵌入式学习之Ubuntu入门(五)汇编语法学习

系列文章目录 一、Linux嵌入式学习之Ubuntu入门&#xff08;一&#xff09;基本命令、软件安装及文件结构 二、Linux嵌入式学习之Ubuntu入门&#xff08;二&#xff09;磁盘文件介绍及分区、格式化等 三、Linux嵌入式学习之Ubuntu入门&#xff08;三&#xff09;用户、用户组…

synchronized原理、偏向锁、轻量级锁、重量级锁、锁升级

文章目录Synchronized概念自增自减字节码指令临界区竞态条件基本使用原理查看synchronized的字节码指令序列Monitor对象的内存布局Mark Word是如何记录锁状态的偏向锁什么是偏向锁偏向锁延迟偏向偏向锁状态跟踪偏向锁撤销之调用对象HashCode偏向锁撤销之调用wait/notify轻量级锁…

Qt Quick - Drawer

Qt Quick - Drawer使用总结一、概述二、使用1、基础使用2、特点空间运行3、与内容转换相互挤占一、概述 Drawer提供了一个基于滑动的侧边面板&#xff0c;类似于经常在触控界面中使用的侧边面板&#xff0c;为导航提供了一个位置。 二、使用 1、基础使用 抽屉可以放置在内…

springcloud深度探索

中文官方文档&#xff1a;project - Spring Cloud Config - 《Spring Cloud中文文档》 - 书栈网 BookStackSpring Cloud ConfigFeaturesQuick StartSample Projects Spring Cloud为开发人员提供了工具&#xff0c;用以快速的在分布式系统中建立一些通用方案&#xff08;例如配…

CDP思科发现协议解析及C/C++代码实现

通常&#xff0c;大多数网络都有几个路由器或交换机&#xff0c;为了便于网络管理&#xff0c;使用网络图或网络图来告诉网络中存在什么类型的设备&#xff0c;以及所有设备如何相互连接&#xff0c;使用的IP地址以及它们属于哪个VLAN的信息。 CDP是一种专有的第二层思科网络协…