/*
头文件article.h
是book,disk,picture的基类,包含基本数据成员的定义,和成员函数的申明
*/
#ifndef ARTICLE_H
#define ARTICLE_H
#include <string>
#include <iostream>
#include <fstream>//该文件是对文件流操作的文件
using namespace std;
class Article
{
private:
int num;
string name;
string author;
public:
Article(int num=0,string name="无",string author="无");
void Show()const;
int getNum(){return num;}
void setNum(int num){this->num=num;}
string getName(){return name;}
void setName(string name){this->name=name;}
string getAuthor(){return author;}
void setAuthor(string author){this->author=author;}
};
#endif
/*
article.cpp
是对article.h文件中相关函数申明的具体实现
*/
#include "article.h"
Article::Article(int num,string name,string author)
{
this->num=num;
this->name=name;
this->author=author;
}
void Article::Show()const
{
cout<<"\t"<<num<<"\t"<<name<<"\t"<<author;
}
/*
articlenode.h
定义物品节点,包括数据成员的定义和相关功能的申明
*/
#ifndef ARTICLENODE_H
#define ARTICLENODE_H
#include "article.h"
//定义链接性为内部的静态数组
static int arr[100];
class ArticleNode
{
private:
Article art;
ArticleNode * part;
public:
ArticleNode();
ArticleNode * AddArticle();
void ShowArticle();
//通过此方法将编号存入arr数组中
void SetNum(int n);
//判断arr数组中是否有编号i
int HasNum(int n);
};
#endif
/*
articlenode.cpp
对节点功能的具体实现
*/
#include "articlenode.h"
ArticleNode::ArticleNode()
{
part=NULL;
}
ArticleNode * ArticleNode::AddArticle()
{
int num;
string name;
string author;
ArticleNode *pnew = new ArticleNode();
cout<<"输入编号(不能为0),名称,作者:(输入数据以空格间隔)"<<endl;
cin>>num>>name>>author;
if(HasNum(num))
{
cout<<"编号已经存在,输入无效\n";
return this;
}
SetNum(num);
Article art = Article(num,name,author);
//头插法建立单链表
pnew->art = art;
if(this->part==NULL)
{
pnew->part=NULL;
}
else
pnew->part=this->part;
this->part = pnew;
delete pnew;
return this;
}
void ArticleNode::ShowArticle()
{
if(this->part!=NULL)
{
ArticleNode *pcurrent;
pcurrent=this->part;
while(pcurrent!=NULL)
{
pcurrent->art.Show();
pcurrent = pcurrent->part;
}
return;
}
cout<<"物品库为空!\n";
}
void ArticleNode::SetNum(int n)
{
for(int i=0;i<100;i++)
{
if(arr[i]==0)
{
arr[i]=n;
break;
}
}
}
int ArticleNode::HasNum(int n)
{
for(int i=0;i<100;i++)
{
if(arr[i]==n)
{
return 1;
}
}
return 0;
}
/*
book.h
包含book私有成员的定义,和不同于基类函数的定义
*/
#ifndef BOOK_H
#define BOOK_H
#include "article.h"
class Book: public Article
{
private:
string press;
int page;
public:
Book(string press="无",int page=0,int num=0,string name="无",string author="无");
Book(string press,int page,const Article & art);
void Show()const;
string getPress(){return press;}
void setPress(string press){this->press=press;}
int getPage(){return page;}
void setPage(int page){this->page=page;}
};
#endif
/*
book.cpp
对book.h中相关函数定义的具体实现
*/
#include "book.h"
Book::Book(string press,int page,int num,string name,string author): Article(num,name,author)
{
this->press=press;
this->page=page;
}
Book::Book(string press,int page,Article const & art): Article(art)
{
this->press=press;
this->page=page;
}
void Book::Show()const
{
Article::Show();
cout<<"\t"<<press<<"\t\t"<<page<<endl;
}
/*
booknode.h
定义图书节点,包括数据成员的定义和相关功能的申明
*/
#ifndef BOOKNODE_H
#define BOOKNODE_H
#include "articlenode.h"
#include "book.h"
//定义物品的数目,初始化为零
static int currentNumBook=0;
//图书节点,光盘节点,图画节点都继承至物品节点
class BookNode: public ArticleNode
{
private:
Book bk;
BookNode * pbk;
public:
//定义构造函数
BookNode();
BookNode * AddBook(int num=0,string name="无",string author="无",string press="无",int page=0);
//显示物品的信息
void ShowBook();
//保存物品,将数据写入到文件中
void SaveBook(ofstream & fwriteBook);
//获得当前的物品数目
int GetCurrentNumBook();
//删除链表中符合要求的物品
bool DeleteBook(int num);
//修改物品信息
bool ReviseBook(int num);
//按编号查询物品信息
bool SearchBook(int num);
//重载函数,按标题查询物品信息
bool SearchBook(string str);
};
#endif
/*
booknode.cpp
对节点功能的具体实现
*/
#include "booknode.h"
BookNode::BookNode()
{
pbk=NULL;
}
//该函数的功能是在图书节点链表中添加新的节点
BookNode * BookNode::AddBook(int num,string name,string author,string press,int page)
{
BookNode *pnew = new BookNode();
//若调用该函数的程序没有传参,则通过控制台传入参数,这种做法的目的是可以将文件中读到的参数传进来,完成添加节点的功能
if(num==0)
{
cout<<"输入编号(不能为0),名称,作者,出版社,页数(整数):(输入数据以空格间隔)\n";
cin>>num>>name>>author>>press>>page;
if(HasNum(num))
{
cout<<"编号已经存在,输入无效\n";
return this;
}
}
SetNum(num);
Book bk = Book(press,page,num,name,author);
//头插法建立单链表
pnew->bk = bk;
if(this->pbk==NULL)
{
pnew->pbk=NULL;
}
else
pnew->pbk=this->pbk;
this->pbk = pnew;
currentNumBook++;
return this;
}
//显示各节点中的数据
void BookNode::ShowBook()
{
if(this->pbk!=NULL)
{
BookNode *pcurrent;
pcurrent=this->pbk;
while(pcurrent!=NULL)
{
pcurrent->bk.Show();
pcurrent = pcurrent->pbk;
}
return;
}
cout<<"\t\t\t 图书库为空\n";
}
//将节点中的数据写入到文件中
void BookNode::SaveBook(ofstream & fwriteBook)
{
if(this->pbk!=NULL)
{
BookNode *pcurrent;
pcurrent=this->pbk;
while(pcurrent!=NULL)
{
//不能将数字与空串相加,否则写文件时出错,导致程序相关功能无法实现
fwriteBook<<pcurrent->bk.getNum()<<" "+pcurrent->bk.getName()+" "<<pcurrent->bk.getAuthor()+" "<<pcurrent->bk.getPress()+" "<<pcurrent->bk.getPage()<<endl;
pcurrent = pcurrent->pbk;
}
return;
}
}
//获得当前的物品数目
int BookNode::GetCurrentNumBook()
{
return currentNumBook;
}
//删除符合要求的节点,向函数中传入删除节点的编号
bool BookNode::DeleteBook(int num)
{
//pfront指针指向要删除节点的前一个节点,pcurrent指针指向要删除的节点。
BookNode * pfront=this;
BookNode * pcurrent=this->pbk;
//此循环的目的是找出要删除的节点
while(pcurrent!=NULL && pcurrent->bk.getNum()!=num)
{
pfront=pcurrent;
pcurrent=pcurrent->pbk;
}
//若满足if的条件证明该节点已经找到,所以if中的语句功能为删除该节点
if(pcurrent!=NULL && pcurrent->bk.getNum()==num)
{
pfront->pbk=pcurrent->pbk;
delete pcurrent;
cout<<"--------------------------------------------------------------------------------";
cout<<"编号为"<<num<<"的物品已经删除"<<endl;\
currentNumBook--;
return true;
}
//若没有找到,返回false
return false;
}
//修改物品信息
bool BookNode::ReviseBook(int num)
{
//pcurrent指针指向要修改的节点。
BookNode * pcurrent=this->pbk;
//此循环的目的是找出要修改的节点
while(pcurrent!=NULL && pcurrent->bk.getNum()!=num)
{
pcurrent=pcurrent->pbk;
}
//若满足if的条件证明该节点已经找到,所以if中的语句功能为修改该节点
if(pcurrent!=NULL && pcurrent->bk.getNum()==num)
{
string name;
string author;
string press;
int page;
cout<<"--------------------------------------------------------------------------------";
cout<<"你将对编号为"<<num<<"的图书信息进行修改\n";
cout<<"输入编号(不能为0),名称,作者,出版社,页数(整数):(输入数据以空格间隔)\n";
cin>>num>>name>>author>>press>>page;
SetNum(num);
pcurrent->bk.setNum(num);
pcurrent->bk.setName(name);
pcurrent->bk.setAuthor(author);
pcurrent->bk.setPress(press);
pcurrent->bk.setPage(page);
cout<<"物品信息修改成功";
return true;
}
//若没有找到,返回false
return false;
}
//按编号查询物品信息
bool BookNode::SearchBook(int num)
{
//pcurrent指针将指向要查询的节点。
BookNode * pcurrent=this->pbk;
//按标题查询物品
while(pcurrent!=NULL && pcurrent->bk.getNum()!=num)
{
pcurrent=pcurrent->pbk;
}
//若满足if的条件证明该节点已经找到
if(pcurrent!=NULL && pcurrent->bk.getNum()==num)
{
cout<<"\t\t\t\t图书:\n";
cout<<"\t编号\t名称\t作者\t出版社\t\t页数\n";
pcurrent->bk.Show();
return true;
}
//若没有找到,返回false
return false;
}
//重载函数,按标题查询物品信息
bool BookNode::SearchBook(string str)
{
//pcurrent指针将指向要查询的节点。
BookNode * pcurrent=this->pbk;
//按标题查询物品
while(pcurrent!=NULL && pcurrent->bk.getName()!=str)
{
pcurrent=pcurrent->pbk;
}
//若满足if的条件证明该节点已经找到
if(pcurrent!=NULL && pcurrent->bk.getName()==str)
{
cout<<"\t\t\t\t图书:\n";
cout<<"\t编号\t名称\t作者\t出版社\t\t页数\n";
pcurrent->bk.Show();
return true;
}
//若没有找到,返回false
return false;
}
/*
disk.h
*/
#ifndef DISK_H
#define DISK_H
#include "article.h"
class Disk: public Article
{
private:
string year;
int time;
public:
Disk(string year="无",int time=0,int num=0,string name="无",string author="无");
Disk(string year,int time,const Article & art);
void Show()const;
string getYear(){return year;}
void setYear(string year){this->year=year;}
int getTime(){return time;}
void setTime(int time){this->time=time;}
};
#endif
/*
disk.cpp
*/
#include "disk.h"
Disk::Disk(string year,int time,int num,string name,string author): Article(num,name,author)
{
this->year=year;
this->time=time;
}
Disk::Disk(string year,int time,const Article & art): Article(art)
{
this->year=year;
this->time=time;
}
void Disk::Show()const
{
Article::Show();
cout<<"\t"<<year<<"\t\t"<<time<<endl;
}
/*
disknode.h
定义图书节点,包括数据成员的定义和相关功能的申明,关于函数功能的说明参见booknode.h文件
*/
#ifndef DISKNODE_H
#define DISKNODE_H
#include "articlenode.h"
#include "disk.h"
//定义物品的数目,初始化为零
static int currentNumDisk=0;
class DiskNode: public ArticleNode
{
private:
Disk dk;
DiskNode * pdk;
public:
DiskNode();
DiskNode * AddDisk(int num=0,string name="无",string author="无",string year="无",int time=0);
void ShowDisk();
void SaveDisk(ofstream & fwriteDisk);
//获得当前的物品数目
int GetCurrentNumDisk();
//删除编号为i的物品
bool DeleteDisk(int num);
//修改物品信息
bool ReviseDisk(int num);
//按编号查询物品信息
bool SearchDisk(int num);
//重载函数,按标题查询物品信息
bool SearchDisk(string str);
};
#endif
/*
disknode.cpp
相关功能的实现类似图书节点,注释参加图书节点的注释
*/
#include "disknode.h"
DiskNode::DiskNode()
{
pdk=NULL;
}
DiskNode * DiskNode::AddDisk(int num,string name,string author,string year,int time)
{
DiskNode *pnew = new DiskNode();
if(num==0)
{
cout<<"输入编号(不能为0),名称,作者,出品年份,作品时长(整数):(输入数据以空格间隔)\n";
cin>>num>>name>>author>>year>>time;
}
if(HasNum(num))
{
cout<<"编号已经存在,输入无效\n";
return this;
}
SetNum(num);
Disk dk = Disk(year,time,num,name,author);
//头插法建立单链表
pnew->dk = dk;
if(this->pdk==NULL)
{
pnew->pdk=NULL;
}
else
pnew->pdk=this->pdk;
this->pdk = pnew;
currentNumDisk++;
return this;
}
void DiskNode::ShowDisk()
{
if(this->pdk!=NULL)
{
DiskNode *pcurrent;
pcurrent=this->pdk;
while(pcurrent!=NULL)
{
pcurrent->dk.Show();
pcurrent = pcurrent->pdk;
}
return;
}
cout<<"\t\t\t 光盘库为空\n";
}
void DiskNode::SaveDisk(ofstream & fwriteDisk)
{
if(this->pdk!=NULL)
{
DiskNode *pcurrent;
pcurrent=this->pdk;
while(pcurrent!=NULL)
{
fwriteDisk<<pcurrent->dk.getNum()<<" "+pcurrent->dk.getName()+" "<<pcurrent->dk.getAuthor()+" "<<pcurrent->dk.getYear()+" "<<pcurrent->dk.getTime()<<endl;
pcurrent = pcurrent->pdk;
}
return;
}
}
//获得当前的物品数目
int DiskNode::GetCurrentNumDisk()
{
return currentNumDisk;
}
//删除符合要求的节点,向函数中传入删除节点的编号
bool DiskNode::DeleteDisk(int num)
{
//pfront指针指向要删除节点的前一个节点,pcurrent指针指向要删除的节点。
DiskNode * pfront=this;
DiskNode * pcurrent=this->pdk;
//此循环的目的是找出要删除的节点
while(pcurrent!=NULL && pcurrent->dk.getNum()!=num)
{
pfront=pcurrent;
pcurrent=pcurrent->pdk;
}
//若满足if的条件证明该节点已经找到,所以if中的语句功能为删除该节点
if(pcurrent!=NULL && pcurrent->dk.getNum()==num)
{
pfront->pdk=pcurrent->pdk;
delete pcurrent;
cout<<"--------------------------------------------------------------------------------";
cout<<"编号为"<<num<<"的物品已经删除"<<endl;\
currentNumDisk--;
return true;
}
//若没有找到,返回false
return false;
}
//修改物品信息
bool DiskNode::ReviseDisk(int num)
{
//pcurrent指针指向要修改的节点。
DiskNode * pcurrent=this->pdk;
//此循环的目的是找出要修改的节点
while(pcurrent!=NULL && pcurrent->dk.getNum()!=num)
{
pcurrent=pcurrent->pdk;
}
//若满足if的条件证明该节点已经找到,所以if中的语句功能为修改该节点
if(pcurrent!=NULL && pcurrent->dk.getNum()==num)
{
string name;
string author;
string year;
int time;
cout<<"--------------------------------------------------------------------------------";
cout<<"你将对编号为"<<num<<"的光盘信息进行修改\n";
cout<<"输入编号(不能为0),名称,作者,出品年份,作品时长(整数):(输入数据以空格间隔)\n";
cin>>num>>name>>author>>year>>time;
SetNum(num);
pcurrent->dk.setNum(num);
pcurrent->dk.setName(name);
pcurrent->dk.setAuthor(author);
pcurrent->dk.setYear(year);
pcurrent->dk.setTime(time);
return true;
}
//若没有找到,返回false
return false;
}
//按编号查询物品信息
bool DiskNode::SearchDisk(int num)
{
//pcurrent指针将指向要查询的节点。
DiskNode * pcurrent=this->pdk;
//此循环的目的是按编号查询物品
while(pcurrent!=NULL && pcurrent->dk.getNum()!=num)
{
pcurrent=pcurrent->pdk;
}
//若满足if的条件证明该节点已经找到
if(pcurrent!=NULL && pcurrent->dk.getNum()==num)
{
cout<<"\t\t\t\t光盘:\n";
cout<<"\t编号\t名称\t作者\t\t出品年份\t\t作品时长\n";
pcurrent->dk.Show();
return true;
}
//若没有找到,返回false
return false;
}
//重载函数,按标题查询物品信息
bool DiskNode::SearchDisk(string str)
{
//pcurrent指针将指向要查询的节点。
DiskNode * pcurrent=this->pdk;
//按标题查询物品
while(pcurrent!=NULL && pcurrent->dk.getName()!=str)
{
pcurrent=pcurrent->pdk;
}
//若满足if的条件证明该节点已经找到
if(pcurrent!=NULL && pcurrent->dk.getName()==str)
{
cout<<"\t\t\t\t光盘:\n";
cout<<"\t编号\t名称\t作者\t\t出品年份\t\t作品时长\n";
pcurrent->dk.Show();
return true;
}
//若没有找到,返回false
return false;
}
/*
picture.h
*/
#ifndef PICTURE_H
#define PICTURE_H
#include "article.h"
class Picture: public Article
{
private:
string country;
int length;
int width;
public:
Picture(string country="无",int length=0,int width=0,int num=0,string name="无",string author="无");
Picture(string country,int length,int width,const Article & art);
void Show()const;
string getCountry(){return country;}
void setCountry(string country){this->country=country;}
int getLength(){return length;}
void setLength(int length){this->length=length;}
int getWidth(){return width;}
void setWidth(int width){this->width=width;}
};
#endif
/*
picture.cpp
*/
#include "picture.h"
Picture::Picture(string country,int length,int width,int num,string name,string author): Article(num,name,author)
{
this->country=country;
this->length=length;
this->width=width;
}
Picture::Picture(string country,int length,int width,const Article & art): Article(art)
{
this->country=country;
this->length=length;
this->width=width;
}
void Picture::Show()const
{
Article::Show();
cout<<"\t"<<country<<"\t\t"<<length<<"\t"<<width<<endl;
}
/*
picturenode.h
定义图书节点,包括数据成员的定义和相关功能的申明,关于函数功能的说明参见booknode.h文件
*/
#ifndef PICTURENODE_H
#define PICTURENODE_H
#include "articlenode.h"
#include "picture.h"
//定义物品的数目,初始化为零
static int currentNumPicture=0;
class PictureNode: public ArticleNode
{
private:
Picture pe;
PictureNode * ppe;
public:
PictureNode();
PictureNode * AddPicture(int num=0,string name="无",string author="无",string country="无",int length=0,int width=0);
void ShowPicture();
void SavePicture(ofstream & fwritePicture);
//获得当前的物品数目
int GetCurrentNumPicture();
//删除编号为i的物品
bool DeletePicture(int num);
//修改物品信息
bool RevisePicture(int num);
//按编号查询物品信息
bool SearchPicture(int num);
//重载函数,按标题查询物品信息
bool SearchPicture(string str);
};
#endif
/*
picturenode.cpp
相关功能的实现类似图书节点,注释参加图书节点的注释
*/
#include "picturenode.h"
PictureNode::PictureNode()
{
ppe=NULL;
}
PictureNode * PictureNode::AddPicture(int num,string name,string author,string country,int length,int width)
{
PictureNode *pnew = new PictureNode();
if(num==0)
{
cout<<"输入编号(不为0),名称,作者,出品国籍,长(整数),宽(整数):(输入数据以空格间隔)\n";
cin>>num>>name>>author>>country>>length>>width;
}
if(HasNum(num))
{
cout<<"编号已经存在,输入无效\n";
return this;
}
SetNum(num);
Picture pe = Picture(country,length,width,num,name,author);
//头插法建立单链表
pnew->pe = pe;
if(this->ppe==NULL)
{
pnew->ppe=NULL;
}
else
pnew->ppe=this->ppe;
this->ppe = pnew;
currentNumPicture++;
return this;
}
void PictureNode::ShowPicture()
{
if(this->ppe!=NULL)
{
PictureNode *pcurrent;
pcurrent=this->ppe;
while(pcurrent!=NULL)
{
pcurrent->pe.Show();
pcurrent = pcurrent->ppe;
}
return;
}
cout<<"\t\t\t 图画库为空\n";
}
void PictureNode::SavePicture(ofstream & fwritePicture)
{
if(this->ppe!=NULL)
{
PictureNode *pcurrent;
pcurrent=this->ppe;
while(pcurrent!=NULL)
{
fwritePicture<<pcurrent->pe.getNum()<<" "+pcurrent->pe.getName()+" "<<pcurrent->pe.getAuthor()+" "<<pcurrent->pe.getCountry()+" "<<pcurrent->pe.getLength()<<" "<<pcurrent->pe.getWidth()<<endl;
pcurrent = pcurrent->ppe;
}
}
}
//获得当前的物品数目
int PictureNode::GetCurrentNumPicture()
{
return currentNumPicture;
}
//删除符合要求的节点,向函数中传入删除节点的编号
bool PictureNode::DeletePicture(int num)
{
//pfront指针指向要删除节点的前一个节点,pcurrent指针指向要删除的节点。
PictureNode * pfront=this;
PictureNode * pcurrent=this->ppe;
//此循环的目的是找出要删除的节点
while(pcurrent!=NULL && pcurrent->pe.getNum()!=num)
{
pfront=pcurrent;
pcurrent=pcurrent->ppe;
}
//若满足if的条件证明该节点已经找到,所以if中的语句功能为删除该节点
if(pcurrent!=NULL && pcurrent->pe.getNum()==num)
{
pfront->ppe=pcurrent->ppe;
delete pcurrent;
cout<<"--------------------------------------------------------------------------------";
cout<<"编号为"<<num<<"的物品已经删除"<<endl;\
currentNumPicture--;
return true;
}
//若没有找到,返回false
return false;
}
//修改物品信息
bool PictureNode::RevisePicture(int num)
{
//pcurrent指针指向要修改的节点。
PictureNode * pcurrent=this->ppe;
//此循环的目的是找出要修改的节点
while(pcurrent!=NULL && pcurrent->pe.getNum()!=num)
{
pcurrent=pcurrent->ppe;
}
//若满足if的条件证明该节点已经找到,所以if中的语句功能为修改该节点
if(pcurrent!=NULL && pcurrent->pe.getNum()==num)
{
string name;
string author;
string country;
int length;
int width;
cout<<"--------------------------------------------------------------------------------";
cout<<"你将对编号为"<<num<<"的图画信息进行修改\n";
cout<<"输入编号(不能为0),名称,作者,出品国籍,长(整数),宽(整数):(输入数据以空格间隔)\n";
cin>>num>>name>>author>>country>>length>>width;
SetNum(num);
pcurrent->pe.setNum(num);
pcurrent->pe.setName(name);
pcurrent->pe.setAuthor(author);
pcurrent->pe.setCountry(country);
pcurrent->pe.setLength(length);
pcurrent->pe.setWidth(width);
return true;
}
//若没有找到,返回false
return false;
}
//按编号查询物品信息
bool PictureNode::SearchPicture(int num)
{
//pcurrent指针将指向要查询的节点。
PictureNode * pcurrent=this->ppe;
//此循环的目的是按编号查询物品
while(pcurrent!=NULL && pcurrent->pe.getNum()!=num)
{
pcurrent=pcurrent->ppe;
}
//若满足if的条件证明该节点已经找到
if(pcurrent!=NULL && pcurrent->pe.getNum()==num)
{
cout<<"\t\t\t\t图画:\n";
cout<<"\t编号\t名称\t作者\t出品国籍\t长\t宽\n";
pcurrent->pe.Show();
return true;
}
//若没有找到,返回false
return false;
}
//重载函数,按标题查询物品信息
bool PictureNode::SearchPicture(string str)
{
//pcurrent指针将指向要查询的节点。
PictureNode * pcurrent=this->ppe;
//按标题查询物品
while(pcurrent!=NULL && pcurrent->pe.getName()!=str)
{
pcurrent=pcurrent->ppe;
}
//若满足if的条件证明该节点已经找到
if(pcurrent!=NULL && pcurrent->pe.getName()==str)
{
cout<<"\t\t\t\t图画:\n";
cout<<"\t编号\t名称\t作者\t出品国籍\t长\t宽\n";
pcurrent->pe.Show();
return true;
}
//若没有找到,返回false
return false;
}
/*
main.cpp
功能要求:
对图书馆的三大类物品资料:图书、光盘、图画进行分类管理。
*/
#include "article.h"//包含物品头文件
#include "articleNode.h"//包含物品节点头文件
#include "booknode.h"//包含图书节点头文件
#include "disknode.h"//包含光盘节点头文件
#include "picturenode.h"//包含图画节点头文件
#include <string>//该文件中包含相关对字符串操作的函数
#include <sstream>//该文件是对字符串流操作的文件
//Menu函数没有封装在类中,这里采用面向过程的思维,menu中定义用户选择菜单的相关操作
void Menu(int i);
//定义具有内部链接性的全局静态变量
static BookNode *pheadBook=new BookNode();//定义一个指向图书头节点的指针,该指针指向的链表将存储有关图书的信息
static DiskNode *pheadDisk=new DiskNode();//定义一个指向光盘头节点的指针,该指针指向的链表将存储有关光盘的信息
static PictureNode *pheadPicture=new PictureNode();//定义一个指向图画头节点的指针,该指针指向的链表将存储有关图画的信息
int main()
{
//对磁盘文件进行读操作,获得相关物品信息,放到链表中,相当于对链表进行初始化
ifstream freadBook = ifstream("book.txt",ios::in);
ifstream freadDisk = ifstream("disk.txt",ios::in);
ifstream freadPicture = ifstream("picture.txt",ios::in);
//判断文件是否已经成功打开,若没有打开文件则退出程序
if(!freadBook.is_open() || !freadDisk.is_open() || !freadPicture.is_open())
{
cout<<"文件不能打开,程序终止\n";
exit(0);
}
//对book.txt中的数据进行读操作,将其数据放到链表中,在内存中放入了有关书籍的信息
string str;
while(!freadBook.eof())
{
//将文件中的内容逐行读入,因为数据存储的时候是每条记录占一行
getline(freadBook,str);
//如果文件中内容为空,则跳出循环
if(str.empty())
break;
//初始化一个字符串流对象,将文件中当前读到的一行数据作为参数传递到流对象中
istringstream sread = istringstream(str);
int num;
string name;
string author;
string press;
int page;
//从字符流中读出相关信息,放到各变量中
sread>>num>>name>>author>>press>>page;
//调用addBook函数,将数据加入到链表中
pheadBook->AddBook(num,name,author,press,page);
}
//关闭文件
freadBook.close();
//对disk.txt中的数据进行读操作,其他相关操作类似于对图书的操作
while(!freadDisk.eof())
{
getline(freadDisk,str);
if(str.empty())
break;
//初始化一个字符串流对象,将文件中当前读到的一行数据作为参数传递到流对象中
istringstream sread = istringstream(str);
int num;
string name;
string author;
string year;
int time;
sread>>num>>name>>author>>year>>time;
pheadDisk->AddDisk(num,name,author,year,time);
}
freadDisk.close();
//对picture.txt中的数据进行读操作
while(!freadPicture.eof())
{
getline(freadPicture,str);
if(str.empty())
break;
//初始化一个字符串流对象,将文件中当前读到的一行数据作为参数传递到流对象中
istringstream sread = istringstream(str);
int num;
string name;
string author;
string country;
int length;
int width;
sread>>num>>name>>author>>country>>length>>width;
pheadPicture->AddPicture(num,name,author,country,length,width);
}
freadPicture.close();
//显示界面菜单,与用户交互
char *a = new char;
cout<<"\n\t\t\t\ttitle:媒体库管理系统\n";
cout<<"--------------------------------------------------------------------------------";
while(1)
{
cout<<"\t\t\t\t1、添加物品\n\t\t\t\t2、显示物品库\n\t\t\t\t3、查询物品\n"
<<"\t\t\t\t4、修改物品\n\t\t\t\t5、删除物品\n\t\t\t\t6、统计物品数\n"
<<"\t\t\t\t7、保存操作\n\t\t\t\t8、清屏\n\t\t\t\t9、退出"<<endl;
cout<<"--------------------------------------------------------------------------------";
cout<<"选择:";
cin>>*a;
//阻止用户非法输入
if(atoi(a)<1)
{
cout<<"菜单选择失败,请重新选择\n";
cout<<"--------------------------------------------------------------------------------";
continue;
}
Menu(atoi(a));
cout<<"--------------------------------------------------------------------------------";
}
return 0;
}
//处理用户的相关选择
void Menu(int i)
{
cout<<"--------------------------------------------------------------------------------";
switch(i)
{
//处理用户对三种物品的添加
case 1:
cout<<"\t\t\t\t1、添加书\n\t\t\t\t2、添加光盘\n\t\t\t\t3、添加图画\n";
cout<<"--------------------------------------------------------------------------------";
cout<<"选择:";
cin>>i;
cout<<"--------------------------------------------------------------------------------";
if(i==1)
pheadBook = pheadBook->AddBook();
else if(i==2)
pheadDisk = pheadDisk->AddDisk();
else if(i==3)
pheadPicture = pheadPicture->AddPicture();
else
cout<<"输入有误\n";
break;
//按一定格式显示三种物品信息
case 2:
cout<<"\t\t\t当前物品库中所有的物品信息如下:\n";
cout<<"\t\t\t\t图书:\n";
cout<<"\t编号\t名称\t作者\t出版社\t\t页数\n";
pheadBook->ShowBook();
cout<<"--------------------------------------------------------------------------------";
cout<<"\t\t\t\t光盘:\n";
cout<<"\t编号\t名称\t作者\t\t出品年份\t\t作品时长\n";
pheadDisk->ShowDisk();
cout<<"--------------------------------------------------------------------------------";
cout<<"\t\t\t\t图画:\n";
cout<<"\t编号\t名称\t作者\t出品国籍\t长\t宽\n";
pheadPicture->ShowPicture();
break;
//根据给定条件查询物品信息
case 3:
cout<<"\t\t\t\t1、按编号查询\n\t\t\t\t2、按标题查询\n\t\t\t\t3、按类别查询\n";
cout<<"--------------------------------------------------------------------------------";
cout<<"选择:";
cin>>i;
cout<<"--------------------------------------------------------------------------------";
if(i==1)
{
cout<<"输入你想查询的物品的编号\n";
cout<<"--------------------------------------------------------------------------------";
cout<<"选择:";
cin>>i;
cout<<"--------------------------------------------------------------------------------";
if(!pheadBook->SearchBook(i))
{
if(!pheadDisk->SearchDisk(i))
{
if(!pheadPicture->SearchPicture(i))
{
cout<<"你输入的编号不存在\n";
}
}
}
}
else if(i==2)
{
string str;
cout<<"输入物品的标题\n";
cout<<"--------------------------------------------------------------------------------";
cout<<"输入:";
cin>>str;
cout<<"--------------------------------------------------------------------------------";
if(!pheadBook->SearchBook(str))
{
if(!pheadDisk->SearchDisk(str))
{
if(!pheadPicture->SearchPicture(str))
{
cout<<"你输入的标题不存在\n";
}
}
}
}
else
{
cout<<"\t\t\t\t1、查询图书\n\t\t\t\t2、查询光盘\n\t\t\t\t3、查询图画\n";
cout<<"--------------------------------------------------------------------------------";
cout<<"选择:";
cin>>i;
cout<<"--------------------------------------------------------------------------------";
if(i==1)
{
cout<<"\t\t\t\t图书:\n";
cout<<"\t编号\t名称\t作者\t出版社\t\t页数\n";
pheadBook->ShowBook();
}
else if(i==2)
{
cout<<"\t\t\t\t光盘:\n";
cout<<"\t编号\t名称\t作者\t\t出品年份\t\t作品时长\n";
pheadDisk->ShowDisk();
}
else if(i==3)
{
cout<<"\t\t\t\t图画:\n";
cout<<"\t编号\t名称\t作者\t出品国籍\t长\t宽\n";
pheadPicture->ShowPicture();
}
else
cout<<"你的选择错误!\n";
}
break;
//修改物品信息
case 4:
cout<<"输入你想修改的物品的编号\n";
cout<<"--------------------------------------------------------------------------------";
cout<<"选择:";
cin>>i;
if(!pheadBook->ReviseBook(i))
{
if(!pheadDisk->ReviseDisk(i))
{
if(!pheadPicture->RevisePicture(i))
{
cout<<"--------------------------------------------------------------------------------";
cout<<"你输入的编号不存在\n";
}
}
}
break;
//根据编号删除物品
case 5:
cout<<"输入你想删除的物品的编号\n";
cout<<"--------------------------------------------------------------------------------";
cout<<"选择:";
cin>>i;
if(!pheadBook->DeleteBook(i))
{
if(!pheadDisk->DeleteDisk(i))
{
if(!pheadPicture->DeletePicture(i))
{
cout<<"--------------------------------------------------------------------------------";
cout<<"你输入的编号不存在\n";
}
}
}
break;
//显示当前物品的数目
case 6:
cout<<"\t\t图书:"<<pheadBook->GetCurrentNumBook();
cout<<"\t\t光盘:"<<pheadDisk->GetCurrentNumDisk();
cout<<"\t\t图画:"<<pheadPicture->GetCurrentNumPicture()<<endl;
break;
//将链表中的数据保存到文件中
case 7:
cout<<"是否保存?(Y/N)\n";
getchar();//清空输入缓冲区中的内容
cout<<"选择:";
if(tolower(getchar())=='y')
{
//对文件进行写操作,将链表中的信息保存到文件中
ofstream fwriteBook = ofstream("book.txt",ios::out);
ofstream fwriteDisk = ofstream("disk.txt",ios::out);
ofstream fwritePicture = ofstream("picture.txt",ios::out);
//判断文件是否已经成功打开,若没有打开文件则退出程序
if(!fwriteBook.is_open() || !fwriteDisk.is_open() || !fwritePicture.is_open())
{
cout<<"文件不能打开,数据保存失败\n";
break;
}
//调用各节点的save函数,将内容保存到文件中
pheadBook->SaveBook(fwriteBook);
pheadDisk->SaveDisk(fwriteDisk);
pheadPicture->SavePicture(fwritePicture);
cout<<"数据保存成功!\n";
}
break;
case 8:
system("cls");
cout<<"\n\t\t\t\ttitle:媒体库管理系统\n";
break;
case 9:
exit(0);
break;
default:
cout<<"输入有误,重新输入:\n";
break;
}
}