媒体库管理系统


写博客也是一种很好的整理学习代码的方式,提升自己的同时,如果能给其他的小伙伴提供帮助将不胜荣幸,给别人讲懂,思路清晰的讲,自己才是真的弄懂。也为了以后查阅方便,特此记录。

一、需求功能描述

1、问题描述
图书馆中的资料很多,如果能分类对其资料流通进行管理,将会带来很多方便,因此要有一个媒体库管理系统图书馆共有三大类物品资料:图书、视频光盘、图画。这三类物品共同具有的属性有:编号、标题、作者、评级(未评级,一般,成人,儿童等。其中图书类增加出版社、ISBN 号、页数等信息;视频光盘类增加出品者的名字、出年份和视频时长等信息;图画类增加出品国籍、作品的长和宽(以厘米计,整数)等信息。
2、功能要求
(1)添加物品:主要完成图书馆三类物品信息的添加,要求编号唯一。当添加了重的编号时,则提示数据添加重复并取消添加;当物品库已满,则提示不能再添加新的数据。
(2)查询物品
可按照三种方式来查询物品,分别为:
按标题查询:输入标题,输出所查询的信息,若不存在该记录,则提示“该标题不存在!”;
按编号查询:输入编号,输出所查询的信息,若不存在该记录,则提示“该编号不存在!”;
按类别查询:输入类别,输出所查询的信息,若不存在记录,则提示“该类别没有物品!”;
(3)显示物品库:输出当前物品库中所有物品信息,每条记录占据一行。
(4)编辑物品:可根据查询结果对相应的记录进行修改,修改时注意编号的唯一性。
(5)删除物品:主要完成图书馆物品信息的删除。如果当前物品库为空,则提示“品库为空!”,并返回操作;否则,输入要删除的编号,根据编号删除该物品的记录,如果编号不在物品库中,则提示“该编号不存在”。
(6)统计信息
输出当前物品库中总物品数,以及按物品类别,统计出当前物品中各类别的物品数并显示。
(7)物品存盘:将当前程序中的物品信息存入文件中。
(8)读出物品:从文件中将物品信息读入程序
题目分析:

1、图书馆中的资料很多,如果能分类对其资料流通进行管理,将会带来很多方便,因此需要有一个媒体库管理系统。
2、媒体库可以对里面的图书、视频光盘、图画进行相关操作。
3、这三类物品共同具有的属性有:编号、标题、作者、评级(未评级,一般,成人,儿童) 等。其中图书类增加出版社、ISBN 号、页数等信息;视频光盘类增加出品者的名字、出品 年份和视频时长等信息;图画类增加出品国籍、作品的长和宽(以厘米计,整数)等信息。
4、 相关功能有添加物品、查询物品、显示物品库、编辑物品、删除物品、统计信息、物品存盘、读出物品等。

二、类设计描述

主要使用了四个类,分别为mediaManage、media、book、video、photo。
其中mediaManage用于主系统以及各个分系统的界面展示。media为book、video、photo的基类,是一个抽象类,用于所有数据的存放,定义了许多纯虚函数用于派生类的继承重写,是一个抽象类。media、book、photo均以公有继承方式继承于media,分别重写了纯虚函数。初始化了构造函数、析构函数。主要思路导图如下:
在这里插入图片描述
类图如下:
在这里插入图片描述

三、核心算法描述

(1)登录界面采用文件文件流将账号密码保存到表格。
(2) 主系统主要采用了go…to…语句用于进入各个分系统。采用if…else语句用于接受用户想要进入的系统以及所想选择的功能。
(3)各个功能均有采用文件流将数据保存到文本文件中、指针数组、数据覆盖、更新数据等。
(4)整体使用了较多的system函数和部分位置使用了弹窗用于提示。
具体设计细节后文有详述。

四、系统实现效果

(1)实现了对登陆人员的身份识别。
(2)实现了对于主系统和各个分系统的展示。
(3)实现了功能模块中的添加物品,可以对图书、视频光盘、图画进行添加。
(4)实现了功能模块中的查询物品,可以采用标题、编号进行查询。
(5)实现了对于物品库的整体信息展示。
(6)实现了可以对现有物品进行信息修改。
(7)实现了可以对现有物品进行信息删除。
(8)实现了可以统计一下整体系统信息并展示。
(9)实现了对于物品的存盘和读取以及修改、删除时本地物品信息的更新。

五、心得体会

设计一个项目不是一个容易的事,但确实很锻炼编程者的代码构架能力,考验设计能力、整体观以及处理问题的能力。
编写代码期间确实出现了n多个错误,也是不断查找资料进行修改,怎么说呢,看见报错不能上来就慌乱,束手无措,应该根据报错内容,积极寻找对策,你不知道的知识点就藏在其中,这也是能提升你代码能力的关键所在。
系统初具雏形时瘦弱不堪,很多个bug,后面通过不断修改,琢磨,调试可以找到一些漏洞,并进行了修改,使系统变得强大起来,可以对不同的输入做出相应反应。

现就其中的一些错误记录一下:

  1. 未找到相应exe文件或者采用外部符号:大概率是因为只定义了函数,而没有实现的部分。(查了好半天,用了好多种办法,结果是这样,裂开)
  2. 解决办法:写完具体函数看看是否还报错,如果暂时用不到该函数只是一个空的,也要写哪怕只是一个花括号
  3. 不允许抽象类实例化:大概率是没有将全部纯虚函数重写
  4. cin和getline同时使用要使用cin.ignore();具体原因参见:[点这里跳转](https://blog.csdn.net/qq_50882544/article/details/113620526

报了好多错误记不清了,先记录这么多,下次一定先记录。

》。。。《

面向对象程序设计项目报告
“ 媒体库管理系统”的设计与实现

媒体库管理系统
**
(**大学 信息科学与工程学院)

摘 要:本系统主要有三大界面,第一个登录界面,第二个主系统,第三个有三个分系统。当用户登录成功时进入主系统,然后选择想要进入的某个系统选择想要功能操作数据;反之如果没有登录成功则不能进入系统对数据进行操作。这样就保证了对人员的识别,系统更具有安全性。三个系统之间独立操作互不干扰,保证了数据更加安全。

六、设计思路详述

因为三个分系统的相关代码较为相似,所以只罗列了图书管理系统的代码及截图展示。

采用多文件操作:

在这里插入图片描述

(1)所有数据的存放

采用了一个基类,用于存放所有数据成员和函数成员,是一个抽象类。定义了很多纯虚函数,方便派生类的继承重写。
allData.h代码如下:

#pragma once
#include<iostream>
using namespace std;
class media {
public:
	virtual void addProject() = 0;//添加物品
	virtual void showAllData() = 0;//统计信息
	virtual void deleteProject() = 0;//删除物品
	virtual void showAllProject() = 0;//显示物品库
	virtual void chushihua() = 0;//初始化指针数组,用于检查编号是否重复
	virtual int isExit(int id) = 0;//用编号检测是否存在某条数据
	virtual int isExit(string tit) = 0;//用标题检测是否存在某条数据
	virtual void findData() = 0;//查询物品
	virtual void output(int initialIndex) = 0;//物品存盘,传入初始下标
	virtual void modifyData() = 0;//修改数据
	virtual void restarDelete(string address,media* tt)=0;//用于修改删除数据的保存(实现原理:逐行读取数据,读到要删除的数据跳过
	//创建临时文件并清空,把数据复制进去,然后再把删完的数据重新写入目标文件
	media** ptr1;//指向图书
	media** ptr2;//指向视频光盘
	media** ptr3;//指向图画	
	int m_FileIsEmpty1;//用于判断存储图书文件是否为空,0---不存在相应保存文件,1---存在文件数据为空,2---存在并且数据不为空。
	int m_FileIsEmpty2;//用于判断存储视频光盘文件是否为空,0---不存在相应保存文件,1---存在文件数据为空,2---存在并且数据不为空。
	int m_FileIsEmpty3;//用于判断存储图画文件是否为空,0---不存在相应保存文件,1---存在文件数据为空,2---存在并且数据不为空。B
	int num;//编号
	string title;//标题
	string writer;//作者
	string rank;//级别
	string publication;//出版社
	string isbn;//ISBN号
	int papers;//页数
	string name;//出品者名字
	int year;//出品年份
	string times;//视频时长
	string pubcou;//出品国家
	int leigth;//长
	int weigth;//宽
	int sum1;//记录可以保留的图书总数
	int sum2;//记录可以保留的视频光盘总数
	int sum3;//记录可以保留的图画总数	
};

此处细节

  1. 定义纯虚函数,基类属于抽象类,不能实例化对象,只能采用指针或者引用
  2. 重写函数时,要实现和声明都要写,否则容易出现一些错误,哪怕实现部分没有具体函数体,只有一个或括号!!!!(这也是所有函数都要注意的!!!!
    3.私有数据要采用protected进行保护,不能用private(派生类访问不到),更不能采用友元函数,因为基类和派生类再声明为友元不合逻辑

(2)登录界面的设计

1.1.1 设计思路叙述
设计之初考虑到 一个系统不能随便使用,应由管理人员进行操控,所以设置了登录界面。当账号密码存在时,可以进入系统对系统中的数据进行操作,反之则不能进入系统。
账号数据被保存到本地的一个名为persons的csv文件中。当用户输入的账号密码可以匹配到本地数据时,进入系统。
1.1.2 代码展示

void ensurePerson() {
	string person; bool bol = false;
	while (true) {
		cout << "************************************************" << endl;
		cout << "********************请先登录********************" << endl;
		cout << "************** 1.登录管理员账号 ****************" << endl;
		cout << "************** 2.添加管理员账号 ****************" << endl;
		cout << "************** 0.退出 **************************" << endl;
		cout << "************************************************" << endl;
		cout << "请输入您要选择的功能:" << endl;
		getline(cin, person);
		if (person == "1") {
			string account, password;
			cout << "请输入账号:"; cin >> account; cin.ignore();
			cout << "请输入密码:"; cin>>password; cin.ignore();
			fstream ifs;
			ifs.open("persons.csv", ios::in);
			string compare = account.append(",").append(password);
			string kk;
			while (getline(ifs, kk)) {
				if (!(kk.compare(compare))) {
					bol = true; break;
				}
			}
			ifs.close();
			if (bol) {
				MessageBox(GetForegroundWindow(), (LPCTSTR)TEXT("身份正确"), (LPCTSTR)TEXT("登录成功"), MB_ICONINFORMATION | MB_OK); system("cls"); break;
			}
			else {
				MessageBox(GetForegroundWindow(), (LPCTSTR)TEXT("身份错误"), (LPCTSTR)TEXT("登录失败"), MB_ICONEXCLAMATION | MB_OK);
			}
			system("cls");
		}
		else if (person == "2") {
			string account, password;
			ofstream ofs;			
			ofs.close();
			cout << "请输入需要添加的管理人员数量:";//询问用户添加的数量,必要时可以连续添加
			int addNum; cin >> addNum; cin.ignore();//存储用户想要添加的图书数量
			if (addNum <= 0) {
				cout << "输入有误,无法添加" << endl;//数量小于等于0无法添加
				system("pause");
			}
			else {
				ofs.open("persons.csv", ios::app);
				for (int i = 0; i < addNum; ++i) {			
					cout << "请输入第"<<i+1<<"个账号:"; cin >> account; cin.ignore();
					cout << "请输入第" << i+1 << "个密码:"; cin >> password; cin.ignore();
					ofs << account << "," << password << endl;
				}
				MessageBox(GetForegroundWindow(), (LPCTSTR)TEXT("成功添加"), (LPCTSTR)TEXT("添加成功"), MB_ICONEXCLAMATION | MB_OK);
			}
			ofs.close();
			system("cls");
		}
		else if (person == "0") {
			int temp = MessageBox(GetForegroundWindow(), (LPCTSTR)TEXT("确认退出嘛?"), (LPCTSTR)TEXT("提示"), MB_ICONQUESTION | MB_YESNO);
			if (temp == 6) {
				MessageBox(GetForegroundWindow(), (LPCTSTR)TEXT("成功退出!"), (LPCTSTR)TEXT("提示"), MB_ICONINFORMATION | MB_OK); exit(0);
			}		
		}
		else {
			cout << "输入有误,请重新输入!" << endl;
			system("pause");
		}	
		system("cls");
	}
}

1.1.3 运行截图展示
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

(3)主菜单的设计

主要是采用if…else…语句对用户输入的选择进行捕捉,运用goto语句实现各个系统的跳转变换。
Main.cpp代码如下:

#pragma once//防止头文件重复包含
#include <iostream>//标准输入输出流
#include"媒体库管理系统.h"
#include"图书.h"
#include"视频光盘.h"
#include"图画.h"
#include"allData.h"
#include<cstdlib>//清屏暂停头文件
#include<fstream>//读取文件
#include<string>
using namespace std;
int main()

    ensurePerson();//登录界面
	mediaManage md;//用于显示主界面和选择相应系统
	media* tt = new book();//用于调用图书系统
	media* tk = new video();//用于调用视频光盘系统
	media* tm = new photo();//用于调用图画系统
	string choice;//用于接受选择系统
	string choice1;//用于接受选择功能
	while (true) {
		md.showMenu();//展示三个系统	
		cout << "请输入您要选择的系统" << endl;
		getline(cin, choice);
		//1.图书管理系统
		if (choice == "1") {
			goto sign1;
		}
		//2.视频光盘管理系统
		else if (choice == "2") {
			goto sign2;
		}
		//3.图画管理系统
		else if (choice == "3") {
			goto sign3;
		}
		//0.退出媒体库管理系统
		else if (choice == "0") {
			md.exitSystem();
		}
		else {
			cout << "输入有误,请重新输入!" << endl;
			system("pause");
		}
	toSign:
		system("cls");
	}
	//进入图书系统
#pragma region 图书系统
	sign1 :
	if (tt->m_FileIsEmpty1 == 0) {
		system("pause");
		goto toSign;
	}
	while (true) {
		system("cls");
		md.showBookFunction(1);
		cout << "请输入您要选择的功能" << endl;
		getline(cin, choice1);
		//1.添加物品
		if (choice1 == "1") {
			tt->addProject();
		}
		//2.查询物品
		else if (choice1 == "2") {
			tt->findData();
		}
		// 3.显示物品库
		else if (choice1 == "3") {
			tt->showAllProject();
		}
		//4.编辑物品
		else if (choice1 == "4") {
			tt->modifyData();
		}
		//5.删除物品
		else if (choice1 == "5") {
			tt->deleteProject();
		}
		//6.统计信息
		else if (choice1 == "6") {
			tt->showAllData();
		}
		//7.返回主系统
		else if (choice1 == "7") {
			goto toSign;//返回主系统
		}
		//8.不进行操作直接退出系统
		else if (choice1 == "8") {
			md.exitSystem();
		}
		else {
			cout << "输入有误,请重新输入!" << endl;
			system("pause");
		}
	}
#pragma endregion
	//进入视频光盘系统
#pragma region 视频光盘系统
	sign2 :
	if (tk->m_FileIsEmpty2 == 0) {
		system("pause");
		goto toSign;
	}
	while (true) {
		system("cls");
		md.showBookFunction(2);
		cout << "请输入您要选择的功能" << endl;
		getline(cin, choice1);
		//1.添加物品
		if (choice1 == "1") {
			tk->addProject();
		}
		//2.查询物品
		else if (choice1 == "2") {
			tk->findData();
		}
		// 3.显示物品库
		else if (choice1 == "3") {
			tk->showAllProject();
		}
		//4.编辑物品
		else if (choice1 == "4") {
			tk->modifyData();
		}
		//5.删除物品
		else if (choice1 == "5") {
			tk->deleteProject();
		}
		//6.统计信息
		else if (choice1 == "6") {
			tk->showAllData();
		}
		//7.返回主系统
		else if (choice1 == "7") {
			goto toSign;//返回主系统
		}
		//8.不进行操作直接退出系统
		else if (choice1 == "8") {
			md.exitSystem();
		}
		else {
			cout << "输入有误,请重新输入!" << endl;
			system("pause");
		}
	}
#pragma endregion
	//进入图画系统
#pragma region 图画系统
	sign3 :	
	if (tm->m_FileIsEmpty3 == 0) {
		system("pause");
		goto toSign;
	}
	while (true) {
		system("cls");
		md.showBookFunction(3);
		cout << "请输入您要选择的功能" << endl;
		getline(cin, choice1);
		//1.添加物品
		if (choice1 == "1") {
			tm->addProject();
		}
		//2.查询物品
		else if (choice1 == "2") {
			tm->findData();
		}
		// 3.显示物品库
		else if (choice1 == "3") {
			tm->showAllProject();
		}
		//4.编辑物品
		else if (choice1 == "4") {
			tm->modifyData();
		}
		//5.删除物品
		else if (choice1 == "5") {
			tm->deleteProject();
		}
		//6.统计信息
		else if (choice1 == "6") {
			tm->showAllData();
		}
		//7.返回主系统
		else if (choice1 == "7") {
			goto toSign;//返回主系统
		}
		//8.不进行操作直接退出系统
		else if (choice1 == "8") {
			md.exitSystem();
		}
		else {
			cout << "输入有误,请重新输入!" << endl;
			system("pause");
		}
	}
#pragma endregion
	system("pause");
	return 0;
}

媒体库管理系统.h代码如下:

#pragma once
#include"allData.h"
#include<iostream>
using namespace std;
class mediaManage {
public:	
	void showMenu();//菜单展示功能
	void exitSystem();//退出系统
	void showBookFunction(int s);//展示图书管理系统
};

媒体库管理系统.cpp代码如下:

#include"媒体库管理系统.h"
#include<iostream>
using namespace std;
//展示三个系统
void mediaManage::showMenu() {
	cout << "************************************************" << endl;
	cout << "******** 欢迎使用媒体库管理系统! **************" << endl;
	cout << "************* 1.图书管理系统 *******************" << endl;
	cout << "*********** 2.视频光盘管理系统 *****************" << endl;
	cout << "************* 3.图画管理系统 *******************" << endl;
	cout << "********** 0.退出媒体库管理系统 ****************" << endl;
	cout << "************************************************" << endl;
}
//退出系统
void mediaManage::exitSystem() {
	cout << "您确定退出系统嘛?请输入是或否" << endl;
	string ss; cin >> ss; cin.ignore();
	if (ss == "是" || ss == "否") {
		if (ss == "是") {
			cout << "已退出系统,欢迎下一次使用" << endl;
			system("pause");
			exit(0);//退出系统
		}
		else {
			system("pause");
			system("cls");
		}
	}
	else {
		cout << "输入有误,请重新选择" << endl;
		system("pause");
		system("cls");
	}
}
//展示图书管理系统
void mediaManage::showBookFunction(int s) {
	cout << "************************************************" << endl;
	switch (s) {
	case 1:
		cout << "******** 欢迎使用图书管理系统! ****************" << endl;
		break;
	case 2:
		cout << "******** 欢迎使用视频光盘管理系统! ************" << endl;
		break;
	case 3:
		cout << "******** 欢迎使用图画管理系统! ****************" << endl;
		break;
	}
	cout << "************* 1.添加物品 ***********************" << endl;
	cout << "************* 2.查询物品 ***********************" << endl;
	cout << "************* 3.显示物品库 *********************" << endl;
	cout << "************* 4.编辑物品 ***********************" << endl;
	cout << "************* 5.删除物品 ***********************" << endl;
	cout << "************* 6.统计信息 ***********************" << endl;
	cout << "************* 7.返回主系统 *********************" << endl;
	cout << "************* 8.不进行操作直接退出系统 *********" << endl;
	cout << "************************************************" << endl;
}

此处细节

  1. 用string接受用户输入,要采用if…else,不能采用switch,switch不能接受string ,如若采用int接受用户输入,不能对用户的恶意输入做出反应。
  2. 定义基类指针时要在前面定义,否则编译不通过,会报错。
  3. goto的跳转要搞清楚。(虽然好像不太提倡用,但是我想不到其他的实现办法了,学的东西太少了,我裂开)

(4)功能模块

1.整体代码展示

其实三个系统的大体代码都差不多,基本上是复制粘贴,只是一些细节问题,要好好纠察,例如具体到哪里用哪个指针,要传入哪个参数,还有名称的改变。因为代码较为相似,所以只列出图书系统的代码。其他的两个代码可由读者自行编写。
图书.h代码如下:

#pragma once
#include<iostream>
#include"allData.h"
using namespace std;
class book :public media {
public:
	book();//默认构造函数
	book(int a, int g, string b, string c, string d, string e, string f);//构造函数
	//a代表编号,b代表标题,c代表作者,d代表评级,e代表出版社,f代表ISBN号,g代表页数
	void addProject();//添加物品
	void showAllData();//统计信息
	void deleteProject();//删除物品
	void showAllProject();//显示物品库
	int getNum();//统计图书系统中当前的数据
	void chushihua();//初始化指针数组,用于检查编号是否重复
	int isExit(int id);//用编号检测是否存在某条数据
	int isExit(string tit);//用标题检测是否存在某条数据
	void findData();//查询物品
	void output(int initialIndex);//物品存盘,传入初始下标
	void modifyData();//修改数据
	void restarDelete(string address, media* tt);//用于修改删除数据的保存
	~book();	
};

图书.cpp代码如下:

#pragma once
#include"图书.h"
#include<string>
#include<iostream>
#include<fstream>
#include<Windows.h>
#define FILENAME1 "book.txt"
#define FILETEMPNAME "temp.txt"
const int SUM = 1000;//每个项目可以保存的最大项目数
using namespace std;
//默认构造函数
book::book() {
	ifstream ifs;
	ifs.open(FILENAME1, ios::in);
	//1.文件不存在
	if (!ifs.is_open()) {
		MessageBox(GetForegroundWindow(), (LPCTSTR)TEXT("!!!暂时无法对图书管理系统进行操作!!!"), (LPCTSTR)TEXT("!!!用于保存图书的文件不存在!!!"), MB_ICONWARNING | MB_OK);
		this->sum1 = 0;//初始化数据为0
		this->ptr1 = NULL;//初始化指针数组为0
		this->m_FileIsEmpty1 = 0;//初始化文件不存在
		ifs.close();
		return;
	}
	//2.文件存在,但是数据为空
	char ch;
	ifs >> ch;
	if (ifs.eof()) {
		this->sum1 = 0;//初始化数据为0
		this->ptr1 = NULL;//初始化指针数组为0
		this->m_FileIsEmpty1 = 1;//初始化文件存在但数据为空
		ifs.close();
		return;
	}
	//3.文件存在并且数据不为空
	this->m_FileIsEmpty1 = 2;
	this->sum1 = this->getNum();//返回总数
	this->ptr1 = new media * [this->sum1];//开辟空间
	this->chushihua();//将文件中的数据保留到数值中
}
//析构函数
book::~book() {//释放ptr1
	if (this->ptr1 != NULL) {
		for (int i = 0; i < this->sum1; ++i) {
			if (this->ptr1[i] != NULL) {
				delete this->ptr1[i];
			}
		}
		this->sum1 = 0;
		delete[] ptr1;
		this->ptr1 = NULL;
	}
}
//构造函数
book::book(int a, int g, string b, string c, string d, string e, string f) {
	//a代表编号,b代表标题,c代表作者,d代表评级,e代表出版社,f代表ISBN号,g代表页数
	this->num = a; this->title = b; this->writer = c;
	this->rank = d; this->publication = e; this->isbn = f; this->papers = g;
}
//添加物品
void book::addProject() {
	if (this->sum1 >SUM) {//当图书库满时,无法添加
		cout << "图书管理系统项目数已满,无法再进行添加!" << endl;
	}
	else {当图书库未满时,可以添加
		cout << "请输入需要添加的图书数量:";//询问用户添加的数量,必要时可以连续添加
		int addNum; cin >> addNum; cin.ignore();//存储用户想要添加的图书数量
		if (addNum <= 0) cout << "输入有误,无法添加" << endl;//数量小于等于0无法添加
		else {
			int newSize = this->sum1 + addNum;//计算当前存储的图书数量。当前=之前+即将储存
			media** tempSpace = new media * [newSize];//开辟新空间
			if (this->ptr1 != NULL) {//将原空间放到新空间上
				for (int i = 0; i < this->sum1; ++i) {
					tempSpace[i] = this->ptr1[i];//将每条记录转移到新空间
				}
			}
			for (int i = 0; i < addNum; ++i) {
				int a, g; string b, c, d, e, f;
				while (true) {
					cout << "请输入第" << i + 1 << "本图书的编号:"; cin >> a; cin.ignore(); cout << endl;
					int kk = this->isExit(a);
					if (kk != -1) {
						cout << "数据添加重复,无法添加,以下是该条数据对应的结果:" << endl;
						cout << "图书编号:" << this->ptr1[kk]->num << "\t标题:" << this->ptr1[kk]->title << "\t作者:" << this->ptr1[kk]->writer << "\t评级:"
							<< this->ptr1[kk]->rank << "\t出版社:" << this->ptr1[kk]->publication << "\tISBN号:" << this->ptr1[kk]->isbn << "\t页数:" << this->ptr1[kk]->papers << endl;
						cout << "请重新输入" << endl;
					}
					else break;
				}			
				cout << "请输入第" << i + 1 << "本图书的标题:"; cin >> b; cin.ignore(); cout << endl;
				cout << "请输入第" << i + 1 << "本图书的作者:"; cin >> c; cin.ignore(); cout << endl;
				while (true) {
					cout << "请输入第" << i + 1 << "本图书的评级(未评级,一般,成人,儿童):"; cin >> d; cin.ignore();
					if (d != "未评级" && d != "一般" && d != "成人" && d != "儿童") {
						cout << "评级输入错误,请重新输入" << endl;
					}
					else break;
				}
				cout << "请输入第" << i + 1 << "本图书的出版社:"; cin >> e; cin.ignore(); cout << endl;
				cout << "请输入第" << i + 1 << "本图书的ISBN号:"; cin >> f; cin.ignore(); cout << endl;
				cout << "请输入第" << i + 1 << "本图书的页数:"; cin >> g; cin.ignore(); cout << endl;
				tempSpace[this->sum1 + i] = new book(a, g, b, c, d, e, f);			
				cout << endl;
			}	
			delete[] this->ptr1;//释放原有空间
			this->ptr1 = tempSpace;//更改新的空间指向
			this->sum1 = newSize;//更新新的个数
			this->m_FileIsEmpty1 = 2;//文件存在并且数据不为空
			cout << "成功添加" << addNum << "条图书信息" << endl;
			//图书物品存盘
			this->output(sum1 - addNum);
		}
		//按任意键清屏回到上一级目录
		system("pause");
		system("cls");
	}
}
//统计信息
void book::showAllData() {
	cout << "媒体库管理系统中总共存在" << this->sum1 + this->sum2 + this->sum3 << "条数据" << endl;
	cout << "图书共" << this->sum1 << "条数据" << endl;
	cout << "视频光盘共" << this->sum2 << "条数据" << endl;
	cout << "图画共" << this->sum3 << "条数据" << endl;
	system("pause");
}
//删除物品
void book::deleteProject() {
	if (this->m_FileIsEmpty1 == 1) {
		cout << "物品库为空" << endl;
		system("pause");
		return;
	}
	else{
		cout << "输入您想要删除的图书编号:";
		int id; cin >> id; cin.ignore();
		int kk = this->isExit(id);
		if (kk != -1) {//编号存在			
			this->restarDelete(FILENAME1,this->ptr1[kk]);//真正文件中删除
			for (int i = kk; i < this->sum1 - 1; ++i) {
				this->ptr1[i] = this->ptr1[i + 1];//数据迁移实现覆盖达到删除目的
			}
			this->sum1--;
			cout << "删除成功" << endl;
		}
		else {//编号不存在
			cout << "未找到该编号,删除失败" << endl;
		}
	}
	system("pause");
}
//显示物品库
void  book::showAllProject() {
	ifstream ifs;
	ifs.open(FILENAME1, ios::in);//打开文件
	if (this->m_FileIsEmpty1 == 1||this->sum1==0) {
		cout << "物品库为空" << endl;
		system("pause");
		return;
	}
	for (int i = 0; i < this->sum1; ++i) {
		cout << "图书编号:" << this->ptr1[i]->num << "\t标题:" << this->ptr1[i]->title << "\t作者:" << this->ptr1[i]->writer << "\t评级:"
			<< this->ptr1[i]->rank << "\t出版社:" << this->ptr1[i]->publication << "\tISBN号:" << this->ptr1[i]->isbn << "\t页数:" << this->ptr1[i]->papers;
		cout << endl;
	}
	ifs.close();
	system("pause");
}
//获取当前数据数
int book::getNum() {
	ifstream ifs;
	ifs.open(FILENAME1, ios::in);//打开文件
	int a, g; string b, c, d, e, f;
	int kk = 0;
	while (ifs >> a >> b >> c >> d >> e >> f >> g) {
		kk++;
	}
	ifs.close();
	return kk;
}
//初始化指针数组,用于检查编号是否重复
void book::chushihua() {
	ifstream ifs;
	ifs.open(FILENAME1, ios::in);
	int a, g; string b, c, d, e, f;
	int index = 0;
	while (ifs >> a >> b >> c >> d >> e >> f >> g) {
		media* temp = new book(a, g, b, c, d, e, f);
		this->ptr1[index] = temp;
		index++;
	}
	ifs.close();//关闭文件
}
//检测是否存在某条数据
//1.按编号查询
int  book::isExit(int id) {
	int index = -1;
	for (int i = 0; i < this->sum1; ++i) {
		if (this->ptr1[i]->num == id)//找到相应数据
		{
			index = i;
			break;
		}
	}
	return index;
}
//2.按标题查询
int book::isExit(string tit) {
	int index = -1;
	for (int i = 0; i < this->sum1; ++i) {
		if (this->ptr1[i]->title == tit)//找到相应数据
		{
			index = i;
			break;
		}
	}
	return index;
}
//查询物品
void book::findData() {
	cout << "请输入查找方式(1.按标题查询--2.按编号查询)" << endl;
	string temp;
	cin >> temp; cin.ignore();
	if (temp == "1") {
		cout << "请输入您要查询的标题" << endl;
		string tit;
		cin >> tit; cin.ignore();
		int kk = this->isExit(tit);
		if (kk == -1) cout << "该标题不存在" << endl;
		else {
			cout << "图书编号:" << this->ptr1[kk]->num << "\t标题:" << this->ptr1[kk]->title << "\t作者:" << this->ptr1[kk]->writer << "\t评级:" <<
				this->ptr1[kk]->rank << "\t出版社:" << this->ptr1[kk]->publication << "\tISBN号:" << this->ptr1[kk]->isbn << "\t页数:" << this->ptr1[kk]->papers << endl;;
		}
		system("pause");
	}
	else if (temp == "2") {
		cout << "请输入您要查询的编号" << endl;
		int did;
		cin >> did; cin.ignore();
		int kk=this->isExit(did);
		if (kk == -1) cout << "该编号不存在" << endl;
		else {
			cout << "图书编号:" << this->ptr1[kk]->num << "\t标题:" << this->ptr1[kk]->title << "\t作者:" << this->ptr1[kk]->writer << "\t评级:"<<
	this->ptr1[kk]->rank << "\t出版社:" << this->ptr1[kk]->publication << "\tISBN号:" << this->ptr1[kk]->isbn << "\t页数:" << this->ptr1[kk]->papers << endl;;
		}
		system("pause");
	}
}
//物品存盘
void  book::output(int initialIndex) {
	int index = initialIndex;
	ofstream ofs;
	ofs.open(FILENAME1, ios::app);
	for (int i = index; i < this->sum1; ++i) {
		ofs << this->ptr1[i]->num << " " << this->ptr1[i]->title << " " << this->ptr1[i]->writer << " " << this->ptr1[i]->rank
			<< " " << this->ptr1[i]->publication << " " << this->ptr1[i]->isbn << " " << this->ptr1[i]->papers << endl;
	}
	ofs.close();
}
//修改物品
void book::modifyData() {
	if (this->m_FileIsEmpty1 == 1) {
		cout << "物品库为空" << endl;
		system("pause");
		return;
	}
	else {
		cout << "请输入您想要查询某条数据的方式然后进行修改(1.按标题查询--2.按编号查询)" << endl;
		string temp;
		cin >> temp; cin.ignore();
		if (temp == "1") {
			cout << "请输入您要修改数据对应的标题" << endl;
			string tit;
			cin >> tit; cin.ignore();
			int kk = this->isExit(tit);
			if (kk == -1) cout << "该标题不存在" << endl;
			else {
				delete this->ptr1[kk];
				cout << "查找到该数据,对应的编号为:" << kk << endl;
				int a, g; string b, c, d, e, f;
				while (true) {
					cout << "请重新输入图书的编号:"; cin >> a; cin.ignore(); cout << endl;
					int kk = this->isExit(a);
					if (kk != -1) {
						cout << "数据添加重复,无法添加,以下是该条数据对应的结果:" << endl;
						cout << "图书编号:" << this->ptr1[kk]->num << "\t标题:" << this->ptr1[kk]->title << "\t作者:" << this->ptr1[kk]->writer << "\t评级:"
							<< this->ptr1[kk]->rank << "\t出版社:" << this->ptr1[kk]->publication << "\tISBN号:" << this->ptr1[kk]->isbn << "\t页数:" << this->ptr1[kk]->papers << endl;
						cout << "请重新输入" << endl;
					}
					else break;
				}
				cout << "请重新输入图书的标题:"; cin >> b; cin.ignore(); cout << endl;
				cout << "请重新输入图书的作者:"; cin >> c; cin.ignore(); cout << endl;
				while (true) {
					cout << "请重新输入图书的评级(未评级,一般,成人,儿童):"; cin >> d; cin.ignore();
					if (d != "未评级" && d != "一般" && d != "成人" && d != "儿童") {
						cout << "评级输入错误,请重新输入" << endl;
					}
					else break;
				}
				cout << "请重新输入图书的出版社:"; cin >> e; cin.ignore(); cout << endl;
				cout << "请重新输入图书的ISBN号:"; cin >> f; cin.ignore(); cout << endl;
				cout << "请重新输入图书的页数:"; cin >> g; cin.ignore(); cout << endl;
				this->ptr1[kk] = new book(a, g, b, c, d, e, f);//用新数据将原始数据覆盖
				//以下用于重写文件
				//首先重建文件然后把指针数组指针内容重新写入
				ofstream ofs(FILENAME1, ios::trunc); ofs.close();//第一步重建文件达到清空数据内容的目的
				this->output(0);
				cout << "修改成功" << endl;
			}
			system("pause");
		}
		else if (temp == "2") {
			cout << "请输入您要修改数据对应的编号" << endl;
			int did;
			cin >> did; cin.ignore();
			int kk = this->isExit(did);
			if (kk == -1) cout << "该编号不存在" << endl;
			else {
				delete this->ptr1[kk];
				cout << "查找到该数据"<< endl;
				int a, g; string b, c, d, e, f;
				while (true) {
					cout << "请重新输入图书的编号:"; cin >> a; cin.ignore(); cout << endl;
					int kk = this->isExit(a);
					if (kk != -1) {
						cout << "数据添加重复,无法添加,以下是该条数据对应的结果:" << endl;
						cout << "图书编号:" << this->ptr1[kk]->num << "\t标题:" << this->ptr1[kk]->title << "\t作者:" << this->ptr1[kk]->writer << "\t评级:"
							<< this->ptr1[kk]->rank << "\t出版社:" << this->ptr1[kk]->publication << "\tISBN号:" << this->ptr1[kk]->isbn << "\t页数:" << this->ptr1[kk]->papers << endl;
						cout << "请重新输入" << endl;
					}
					else break;
				}
				cout << "请重新输入图书的标题:"; cin >> b; cin.ignore(); cout << endl;
				cout << "请重新输入图书的作者:"; cin >> c; cin.ignore(); cout << endl;
				while (true) {
					cout << "请重新输入图书的评级(未评级,一般,成人,儿童):"; cin >> d; cin.ignore();
					if (d != "未评级" && d != "一般" && d != "成人" && d != "儿童") {
						cout << "评级输入错误,请重新输入" << endl;
					}
					else break;
				}
				cout << "请重新输入图书的出版社:"; cin >> e; cin.ignore(); cout << endl;
				cout << "请重新输入图书的ISBN号:"; cin >> f; cin.ignore(); cout << endl;
				cout << "请重新输入图书的页数:"; cin >> g; cin.ignore(); cout << endl;				
				this->ptr1[kk] = new book(a, g, b, c, d, e, f);//用新数据将原始数据覆盖	
				//以下用于重写文件
				//首先重建文件然后把指针数组指针内容重新写入
				ofstream ofs(FILENAME1, ios::trunc); ofs.close();//第一步重建文件达到清空数据内容的目的
				this->output(0);
				cout << "修改成功" << endl;
			}
			system("pause");
		}
	}
}
//用于删除数据和修改数据的保存
void book::restarDelete(string address,media *tt) {
	fstream in; in.open(address, ios::in);//创建流对象,读取目标文件
	fstream out; out.open(FILETEMPNAME, ios::out,ios::trunc);//创建流对象,写入临时文件
	string str = to_string(tt->num).append(" ").append(tt->title).append(" ").append(tt->writer).append(" ").append(tt->media::rank)
		.append(" ").append(tt->publication).append(" ").append(tt->isbn).append(" ").append(to_string(tt->papers));
		//to_string方法用于将int强转string,str为book.txt中需要删除的某一行内容,
	string kk;
	while (getline(in, kk)) {
		if (!kk.compare(str)) {//比较book.txt每一行的内容和要删除的是否一致,一致就跳过。compare函数相同返回0,不同返回非0
			continue;
		}
		out << kk << endl;//不一致的内容写到temp.txt中,注意换行
	}
	in.close();
	out.close();//关闭流文件
	fstream outfile(FILENAME1, ios::out);//创建流对象,写入目标文件
	fstream infile(FILETEMPNAME, ios::in);//创建流对象,读取临时文件
	while (getline(infile, kk)) {//将临时文件中的删除完毕的数据写入到目标文件
		outfile << kk << endl;
	}
	outfile.close();
	infile.close();//关闭流对象
}

2.默认构造函数

创建了流对象用于读取,此处要分三种情况

  1. 文件不存在:停止对该系统的操作,并把总数和指针数组置空、将用于判断是否文件为空的数据赋0
  2. 文件存在,但是数据为空:停止对该系统的操作,并把总数和指针数组置空、将用于判断是否文件为空的数据赋1
  3. 文件存在并且数据不为空:调用计数函数getNum()赋值给总数,并为指针数组开辟空间,将用于判断是否文件为空的数据赋2

3.构造函数

这里没有什么好说的,就是为相应的数据赋值,但是要注意在不同的系统中要用不同的指针给不同的数据赋值。要加小心,极易出错。

4.析构函数

将指针数组中的元素置空,将指针数组置空。

5.添加物品

  1. 判断是否超过最大存储数据
  2. 询问用户添加数目
  3. 调用isExit函数判断是否编号重复,如若重复持续输入
  4. 评级如若重复持续输入
  5. 创建新指针数组,将之前的数据迁移,并输入新数据。
  6. 改变指针指向,将新指针数组对指针数组赋值。
  7. 释放相应指针,调用output函数将数据存盘。

6.统计信息

简单输出总数和对应系统数目

7.删除物品

  1. 判断是否为空
  2. 输入编号调用isExit判断是否存在,存在即删除,不存在即退出
  3. 调用restarDelete函数实现文件中的数据删除
  4. 将指针数组中的数据相应迁移实现覆盖删除

8.显示物品库

创建流对象用于读取,逐行读取输出

9.获取数据数

创建流对象,逐行读取,成功即加1

10.初始化指针

将文本文件中的数据逐行读入指针数组

11.检查是否存在某条数据的函数

  1. 按编号查询(查询到返回下标,没查到返回-1)
  2. 按标题查询(查询到返回下标,没查到返回-1)

12.查询物品

同样的提供两种方式查询

  1. 按编号查询(调用相应函数,找到数据输出或未找到提示不存在)
  2. 按标题查询(调用相应函数,找到数据输出或未找到提示不存在)

13.物品存盘

创建流对象,采用追加方式将相应数据写入文件

14.修改物品

先查询,找到后调用restarDelete函数对新数据写入

15.删除数据和修改数据的保存

实现原理:逐行读取数据,读到要删除的数据跳过,创建临时文件并清空,把数据复制进去,然后再把删完的数据重新写入目标文件。类似实现两个数字交换一样,只不过现在是两个文件中的内容交换。

四、运行截图展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

五、尚待解决

  1. bug之一:录入的时候无法判断编号重复。比如输入2个,第1个和第2个重复(emmmm懒得改了,以后有时间再说)
  2. 未使用数据库(时间有点紧,没来的及学习,只学了个皮毛,暂且不太会运用)
  • 8
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

撑一把纸伞.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值