这是一次实验报告,说实话我们大二才做这个实验着实有点晚了,这其实相当于大一的一次课程设计,只不过用的是面向对象写的,这个程序大概写了我三个晚上吧,通宵那种的。现在贴出来给广大网友分享,同时做个记录。需要说明的一点是,系统提供了两种写入图书信息的方式,一个是在系统内按照提示输入图书信息,一种是在指定目录的文件直接存入。系统内输入的都好说,按照系统体术输入就行了,值得注意的是文件录入方式。在文件内直接写入要按照此格式写入,不能多打一行的空回车。这是由于这样直接打开文件的话读起来比较美观,当然你完全可以写成一行,这样固然可以,但是读起来很不方便,而且你需要改写读写相关代码。使用这一方法在系统内只需选择对应功能然后输入待添加的图书文件(一个是原文件,一个是待添加到原文的文件,两个都需要用下面的格式)
《高等数学》 宁小青 科学出版社 1002 1949/5/10 23 理科
《c++程序设计》 陈灯 科学出版社 1003 2003/9/10 45 工科
《线性代数》 罗进 科学出版社 1001 1999/9/10 56 理科
《自然》 Ricardo 高教出版社 1006 1998/9/10 67 核心期刊
《新华字典》 新华 新华出版社 1007 2008/9/10 78 工具
运用面向对象的方法设计“图书管理系统”
编写实现图书信息的输入、显示、查找、添加、删除、保存、排序等功能的函数;
图书分为教材,参考书,期刊等;需提供多态例子;
应提供键盘式选择菜单实现功能选择;
数据输入和结果输出要用文件存放。
注:
1)图书信息包括:图书编号、书名、作者、出版社、出版时间、价格;
2)数据输入要求实现2种功能,即可以从键盘输入也可以从文件“book.txt”输入;
3)查找需要按照不同字段都可以进行查找,如按编号查找、按书名查找等;
4)删除需要按照不同字段都可以进行删除,如按编号删除、按书名删除等;
5)排序需要按照不同字段都可以进行排序(升序和降序),如按编号排序、按书名排序等;
6)结果存入文件“book.txt”中。
E:\\code\\book.txt
主要思路其实很简单,面向对象的思想其实能很容易的编写这个程序,每个图书都是一个对象,它的各个属性都是它的数据成员。关于函数成员本程序其实没有用很多,除了常规的构造函数和输出函数并没有过多的编写。要实现以上功能我们c++的标准模板库stl一定程度上是强有力的工具,不仅能够简化我们的编写,而且里面函数的算法也比一般程序员编写的要更好。我们这里面主要就是用一个vector容器来储存我们的对象,每次更新图书信息就更新我们的容器,所以我们的操作其实实际上就是对容器进行操作,操作完后再把它写入文件就行了,而操作容器又有专门的算法和迭代器,所以我们只需要知道怎么用它即可。
我大一的时候学c语言的时候学到链表也做过一个十分简易的学生管理系统,但是远没有这么多功能,仅仅是熟悉链表的使用。链表这东西有带头节点的,有不带头节点的,双链,单链,十分麻烦,但是我们c++的vector容器统统帮我们解决了,我们尽管用就行了
下面给出代码。在运行代码前要事先准备好待添加文件,否则你会发现什么也没添加进去因为它是刚刚创建的新文件
/*
1. 运用面向对象的方法设计“图书管理系统”
题目要求:
编写实现图书信息的输入、显示、查找、添加、删除、保存、排序等功能的函数;
图书分为教材,参考书,期刊等;需提供多态例子;
应提供键盘式选择菜单实现功能选择;
数据输入和结果输出要用文件存放。
注:
1)图书信息包括:图书编号、书名、作者、出版社、出版时间、价格;
2)数据输入要求实现2种功能,即可以从键盘输入也可以从文件“book.txt”输入;
3)查找需要按照不同字段都可以进行查找,如按编号查找、按书名查找等;
4)删除需要按照不同字段都可以进行删除,如按编号删除、按书名删除等;
5)排序需要按照不同字段都可以进行排序(升序和降序),如按编号排序、按书名排序等;
6)结果存入文件“book.txt”中。
E:\\code\\book.txt
*/
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
class Book
{
public:
string name; //书名
string writer; //作者
string press; //出版社
int number; //编号e书号
string date; //日期
int price; //价格
string temp;
Book() {}
Book(string a, string b, string c, string d, int x, int y, string s)
{
name = a;
writer = b;
press = c;
date = d;
number = x;
price = y;
temp = s;
}
virtual void show()
{
cout.setf(ios::left);
cout << setfill('-') << setw(20) << name << setfill('-') << setw(20) << writer << setfill('-') << setw(20) << press << setfill('-') << setw(20) << number << setfill('-') << setw(20) << date << setfill('-') << price << endl;
}
};
class Testbook : public Book //教材
{
public:
string sub; //学科
Testbook(string a, string b, string c, string d, int x, int y, string s, string e) : Book(a, b, c, d, x, y, s), sub(e) {}
virtual void show()
{
cout.setf(ios::left);
cout << setfill('-') << setw(20) << name << setfill('-') << setw(20) << writer << setfill('-') << setw(20) << press << setfill('-') << setw(20) << number << setfill('-') << setw(20) << date << setfill('-') << setw(20) << price << sub << endl;
}
};
class Referencebook : public Book //参考书
{
public:
string kind; //种类
Referencebook(string a, string b, string c, string d, int x, int y, string s, string e) : Book(a, b, c, d, x, y, s), kind(e) {}
virtual void show()
{
cout.setf(ios::left);
cout << setfill('-') << setw(20) << name << setfill('-') << setw(20)
<< writer << setfill('-') << setw(20)
<< press << setfill('-') << setw(20)
<< number << setfill('-') << setw(20)
<< date << setfill('-') << setw(20)
<< price << kind << endl;
}
};
class Journal : public Book //期刊
{
public:
string grade; //级别
Journal(string a, string b, string c, string d, int x, int y, string s, string e) : Book(a, b, c, d, x, y, s), grade(e) {}
virtual void show()
{
cout.setf(std::ios::left);
cout << setfill('-') << setw(20) << name << setfill('-') << setw(20)
<< writer << setfill('-') << setw(20)
<< press << setfill('-') << setw(20)
<< number << setfill('-') << setw(20)
<< date << setfill('-') << setw(20)
<< price << grade << endl;
}
};
void show(vector<Book> &v)
{
cout.setf(std::ios::left);
cout << setfill(' ') << setw(20) << "| name" //表头
<< setfill(' ') << setw(20) << "writer"
<< setfill(' ') << setw(20) << "press"
<< setfill(' ') << setw(20) << "number"
<< setfill(' ') << setw(20) << "date"
<< setfill(' ') << setw(20) << "price|" << endl
<< endl;
for (int i = 0; i < v.size(); ++i) //输出展示跟新后的图书目
{
cout << setfill('-') << setw(20) << v[i].name
<< setfill('-') << setw(20) << v[i].writer
<< setfill('-') << setw(20) << v[i].press
<< setfill('-') << setw(20) << v[i].number
<< setfill('-') << setw(20) << v[i].date
<< v[i].price << endl
<< endl;
}
}
void delate(vector<Book> &v)
{
vector<Book>::iterator d; //定义正向迭代器
cout.setf(std::ios::left);
cout << "-----------------------------------------------------" << endl;
cout << setfill('-') << setw(20) << "按书名删除"
<< "1" << endl
<< endl;
cout << setfill('-') << setw(20) << "按作者删除"
<< "2" << endl
<< endl;
cout << setfill('-') << setw(20) << "按出版社删除"
<< "3" << endl
<< endl;
cout << setfill('-') << setw(20) << "按编号删除"
<< "4" << endl
<< endl;
cout << setfill('-') << setw(20) << "按出版日删除"
<< "5" << endl
<< endl;
cout << setfill('-') << setw(20) << "按价格删除"
<< "6" << endl
<< endl;
cout << "-----------------------------------------------------" << endl;
/*
由于vector.begin() 和vector.end()是变化的,因此就引入了错误的可能性。
for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
{
if( *iter == 3)
veci.erase(iter);
}
乍一看这段代码,很正常。其实这里面隐藏着一个很严重的错误:当veci.erase(iter)之后,iter就变成了一个野指针,对
一个野指针进行 iter++ 是肯定会出错的。查看MSDN,对于erase的返回值是这样描述的:An iterator that designates
the first element remaining beyond any elements removed, or a pointer to the end of the vector if no
such element exists,于是改代码:
for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
{
if( *iter == 3)
iter = veci.erase(iter);
}
这段代码也是错误的:1)无法删除两个连续的"3"; 2)当3位于vector最后位置的时候,也会出错(在veci.end()上执行 ++ 操作)
正确的代码应该为:
for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); )
{
if( *iter == 3)
iter = veci.erase(iter);
else
iter ++ ;
}
*/
int cho;
cin >> cho;
if (cho == 4)
{
int n; //存储编号;
cout << "输入编号:";
cin >> n;
for (d = v.begin(); d != v.end();)
{
if (d->number == n)
{
d = v.erase(d);
}
else
d++;
}
}
if (cho == 2)
{
string wr; //存储名字
cout << "输入作者:";
cin >> wr;
for (d = v.begin(); d != v.end();)
{
if (d->writer == wr)
{
d = v.erase(d);
}
else
d++;
}
}
if (cho == 3)
{
string pre; //存储出版社
cout << "输入出版社:";
cin >> pre;
for (d = v.begin(); d != v.end();)
{
if (d->press == pre)
{
d = v.erase(d);
}
else
d++;
}
}
if (cho == 5)
{
string dat; //存储日期
cout << "输入日期(XXXX/x/x):";
cin >> dat;
for (d = v.begin(); d != v.end();)
{
if (d->date == dat)
{
d = v.erase(d);
}
else
d++;
}
}
if (cho == 6)
{
int pri; //存储价格
cout << "输入价格:";
cin >> pri;
for (d = v.begin(); d != v.end();)
{
if (d->price == pri)
{
d = v.erase(d);
}
else
d++;
}
}
if (cho == 1)
{
string nam; //存储书名
cout << "输入书名:";
cin >> nam;
for (d = v.begin(); d != v.end();)
{
if (d->name == nam)
{
d = v.erase(d);
}
else
d++;
}
}
show(v);
}
void Find(vector<Book> &v)
{
cout << "-----------------------------------------------------" << endl;
cout << setfill('-') << setw(20) << "按书名查找"
<< "1" << endl
<< endl;
cout << setfill('-') << setw(20) << "按出版社查找"
<< "3" << endl
<< endl;
cout << setfill('-') << setw(20) << "按作者查找"
<< "2" << endl
<< endl;
cout << setfill('-') << setw(20) << "按编号查找"
<< "4" << endl
<< endl;
cout << setfill('-') << setw(20) << "按出版日查找"
<< "5" << endl
<< endl;
cout << setfill('-') << setw(20) << "按价格查找"
<< "6" << endl
<< endl;
cout << "-----------------------------------------------------" << endl;
int f;
cin >> f;
if (f == 1)
{
cout << "输入查找的书名" << endl;
string n;
cin >> n; //编号
cout.setf(std::ios::left);
cout << setfill(' ') << setw(20) << "| name" //表头
<< setfill(' ') << setw(20) << "writer"
<< setfill(' ') << setw(20) << "press"
<< setfill(' ') << setw(20) << "number"
<< setfill(' ') << setw(20) << "date"
<< setfill(' ') << setw(20) << "price|" << endl
<< endl;
for (int i = 0; i < v.size(); i++)
{
if (n == v[i].name)
{
v[i].show();
}
}
}
if (f == 6)
{
cout << "输入查找的价格" << endl;
int n;
cin >> n; //编号
cout.setf(std::ios::left);
cout << setfill(' ') << setw(20) << "| name" //表头
<< setfill(' ') << setw(20) << "writer"
<< setfill(' ') << setw(20) << "press"
<< setfill(' ') << setw(20) << "number"
<< setfill(' ') << setw(20) << "date"
<< setfill(' ') << setw(20) << "price|" << endl
<< endl;
for (int i = 0; i < v.size(); i++)
{
if (n == v[i].price)
{
v[i].show();
}
}
}
if (f == 5)
{
cout << "输入查找的出版日期(xxxx/xx/xx)" << endl;
string n;
cin >> n; //编号
cout.setf(std::ios::left);
cout << setfill(' ') << setw(20) << "| name" //表头
<< setfill(' ') << setw(20) << "writer"
<< setfill(' ') << setw(20) << "press"
<< setfill(' ') << setw(20) << "number"
<< setfill(' ') << setw(20) << "date"
<< setfill(' ') << setw(20) << "price|" << endl
<< endl;
for (int i = 0; i < v.size(); i++)
{
if (n == v[i].date)
{
v[i].show();
}
}
}
if (f == 3)
{
cout << "输入查找的出版社" << endl;
string n;
cin >> n; //编号
cout.setf(std::ios::left);
cout << setfill(' ') << setw(20) << "| name" //表头
<< setfill(' ') << setw(20) << "writer"
<< setfill(' ') << setw(20) << "press"
<< setfill(' ') << setw(20) << "number"
<< setfill(' ') << setw(20) << "date"
<< setfill(' ') << setw(20) << "price|" << endl
<< endl;
for (int i = 0; i < v.size(); i++)
{
if (n == v[i].press)
{
v[i].show();
}
}
}
if (f == 2)
{
cout << "输入查找的作者" << endl;
string n;
cin >> n; //编号
cout.setf(std::ios::left);
cout << setfill(' ') << setw(20) << "| name" //表头
<< setfill(' ') << setw(20) << "writer"
<< setfill(' ') << setw(20) << "press"
<< setfill(' ') << setw(20) << "number"
<< setfill(' ') << setw(20) << "date"
<< setfill(' ') << setw(20) << "price|" << endl
<< endl;
for (int i = 0; i < v.size(); i++)
{
if (n == v[i].writer)
{
v[i].show();
}
}
}
if (f == 4)
{
cout << "输入查找的编号" << endl;
int n;
cin >> n; //编号
cout.setf(std::ios::left);
cout << setfill(' ') << setw(20) << "| name" //表头
<< setfill(' ') << setw(20) << "writer"
<< setfill(' ') << setw(20) << "press"
<< setfill(' ') << setw(20) << "number"
<< setfill(' ') << setw(20) << "date"
<< setfill(' ') << setw(20) << "price|" << endl
<< endl;
for (int i = 0; i < v.size(); i++)
{
if (n == v[i].number)
{
v[i].show();
}
}
}
}
/*
用自定义的类型进行sort算法,
函数名写道sort的第三个参数上 compnumber ,compwriter等
这时候需要自己定义个比较函数,因为sort算法是基于容器中的元素是可以两两比较的,然后从小到大排序,所以要自定义怎么样才是小于('<')
*/
bool compnumber(const Book &a, const Book &b)
{
return a.number < b.number;
}
bool compwriter(const Book &a, const Book &b)
{
return a.writer < b.writer;
}
bool compdate(const Book &a, const Book &b)
{
return a.date < b.date;
}
bool compprice(const Book &a, const Book &b)
{
return a.price < b.price;
}
bool compname(const Book &a, const Book &b)
{
return a.name < b.name;
}
bool comppress(const Book &a, const Book &b)
{
return a.press < b.press;
}
//----------------------------降序排列定义------
bool dcompnumber(const Book &a, const Book &b)
{
return a.number > b.number;
}
bool dcompwriter(const Book &a, const Book &b)
{
return a.writer > b.writer;
}
bool dcompdate(const Book &a, const Book &b)
{
return a.date > b.date;
}
bool dcompprice(const Book &a, const Book &b)
{
return a.price > b.price;
}
bool dcompname(const Book &a, const Book &b)
{
return a.name > b.name;
}
bool dcomppress(const Book &a, const Book &b)
{
return a.press > b.press;
}
void Rank(vector<Book> &v)
{
cout << "--------------------------选择排序方式----------------------" << endl;
cout << setfill('-') << setw(20) << "按书名排序"
<< "1" << endl
<< endl;
cout << setfill('-') << setw(20) << "按作者排序"
<< "2" << endl
<< endl;
cout << setfill('-') << setw(20) << "按出版社排序"
<< "3" << endl
<< endl;
cout << setfill('-') << setw(20) << "按编号排序"
<< "4" << endl
<< endl;
cout << setfill('-') << setw(20) << "按出版日排序"
<< "5" << endl
<< endl;
cout << setfill('-') << setw(20) << "按价格排序"
<< "6" << endl
<< endl;
cout << "-----------------------------------------------------" << endl;
int r;
cin >> r;
cout << "升序--------1" << endl;
cout << "降序--------0" << endl;
int r1;
cin >> r1;
if (r1 == 1)
{
if (r == 4)
{
sort(v.begin(), v.end(), compnumber);
}
if (r == 1)
{
sort(v.begin(), v.end(), compname);
}
if (r == 2)
{
sort(v.begin(), v.end(), compwriter);
}
if (r == 5)
{
sort(v.begin(), v.end(), compdate);
}
if (r == 6)
{
sort(v.begin(), v.end(), compprice);
}
if (r == 3)
{
sort(v.begin(), v.end(), comppress);
}
}
if (r1 == 0)
{
if (r == 4)
{
sort(v.begin(), v.end(), dcompnumber);
}
if (r == 1)
{
sort(v.begin(), v.end(), dcompname);
}
if (r == 2)
{
sort(v.begin(), v.end(), dcompwriter);
}
if (r == 5)
{
sort(v.begin(), v.end(), dcompdate);
}
if (r == 6)
{
sort(v.begin(), v.end(), dcompprice);
}
if (r == 3)
{
sort(v.begin(), v.end(), dcomppress);
}
}
show(v);
}
int main()
{
/*
ofstream bookfile("book2.txt",ios::out);//创建并打开book文件
if(!bookfile)
{
cerr<<"open erro!"<<endl;
exit(1);
}
*/
cout << "-------------------------"
<< "小杰图书管理系统欢迎您"
<< "-----------------------" << endl;
cout << "请输入学号:";
string stu;
cin >> stu;
if (stu == "1805120905")
{
cout << "您好,樊煦杰" << endl;
}
else
cout << "您好,游客" << endl;
cout << "请输入图书信息目录以进行管理操作" << endl;
string add; //用来存放book的路径信息
cin >> add; //E:\\code\\book.txt
Book b; //这是一个临时对象,用来给容器添加元素
vector<Book> v; //定义一个容器,可变数组v;
ifstream infile(add, ios::in); //只读的方式打开文件,读取文件用于给数组进行输入
string temp0; //用来储存每种特图书的特殊属性
int s = 0;
for (s = 0; !infile.eof(); s++) //把文件里的信息传给对象b;
{
infile >> b.name >> b.writer >> b.press >> b.number >> b.date >> b.price >> b.temp; //把文件里的信息传给对象b;
v.push_back(b); //把对象b添加到v里面成为一个元素
}
infile.close();
Book *p; //基类指针,用于调用虚函数
/*
for(int n=0;n<5;++n)
{
p=&b;
p->show();
}
*/
show(v);
//-------------------------------------------------------------以上都是对管理系统进行初始化
part1:
cout << "请选择要执行的操作:" << endl
<< endl;
cout << "----------------------------------------" << endl;
cout << "1-------添加图书" << endl
<< endl;
cout << "2-------删除图书" << endl
<< endl;
cout << "3-------查找图书" << endl
<< endl;
cout << "4-------图书排序" << endl
<< endl;
cout << "----------------------------------------" << endl;
int c;
cin >> c;
if (c == 4)
{
part5:
string temp4;
Rank(v);
part41:
cout << "返回主菜单-----------1" << endl;
cout << "切换排序方法---------0" << endl;
int r;
cin >> r;
if (r == 1)
{
cout << "-----------是否保存?----------" << endl;
cout << "1--------------保存" << endl;
cout << "2-------------不保存" << endl
<< endl;
int ran;
cin >> ran;
if (ran == 1)
{
ofstream bookfile(add, ios::out); //创建并打开book文件
if (!bookfile)
{
cerr << "open erro!" << endl;
exit(1);
}
for (int i = 0; i < v.size(); ++i)
{
if (i != 0)
{
bookfile << endl;
}
bookfile << v[i].name << " " << v[i].writer << " " << v[i].press << " " << v[i].number << " " << v[i].date << " " << v[i].price << " " << v[i].temp;
}
bookfile.close();
goto part1;
}
else
goto part1;
}
if (r == 0)
{
goto part5;
}
else
{
cout << "erro!!" << endl;
goto part41;
}
}
if (c == 3)
{
part4:
Find(v);
cout << endl;
cout << "---------------------是否继续查找?-------------------" << endl;
cout << "继续查找-------0" << endl
<< "返回主菜单-----1" << endl;
int fin;
cin >> fin;
if (fin == 0)
{
goto part4;
}
goto part1;
}
if (c == 2)
{
part3:
string temp3;
delate(v);
cout << "是否继续删除?" << endl;
cout << "继续删除-------0" << endl
<< "返回主菜单-----1" << endl;
int del;
cin >> del;
if (del == 0)
{
goto part3;
}
if (del == 1)
{
cout << "-----------是否保存?----------" << endl;
cout << "1--------------保存" << endl;
cout << "2-------------不保存" << endl
<< endl;
int de;
cin >> de;
if (de == 1)
{
ofstream bookfile(add, ios::out); //创建并打开book文件
if (!bookfile)
{
cerr << "open erro!" << endl;
exit(1);
}
for (int i = 0; i < v.size(); ++i)
{
if (i != 0)
{
bookfile << endl;
}
bookfile << v[i].name << " " << v[i].writer << " " << v[i].press << " " << v[i].number << " " << v[i].date << " " << v[i].price << " " << v[i].temp;
}
bookfile.close();
goto part1;
}
else
goto part1;
}
}
if (c == 1)
{
cout << "请选择添加方式:" << endl
<< endl;
cout << "1-------以文件方式添加" << endl
<< "2----------直接输入" << endl;
cout << "请选择添加方式:" << endl
<< endl;
int t;
cin >> t;
if (t == 2)
{
string temp22;
part2:
ofstream bookfile2(add, ios::app); //以添加方式打开book文件
if (!bookfile2)
{
cerr << "open erro!" << endl;
exit(1);
}
cout << "书名:";
cin >> b.name;
cout << "作者:";
cin >> b.writer;
cout << "出版社:";
cin >> b.press;
cout << "编号:";
cin >> b.number;
cout << "出版日期:";
cin >> b.date;
cout << "价格:";
cin >> b.price;
cout << "属性:";
cin >> b.temp; //先输入给一个临时对象
v.push_back(b); //把刚刚的临时对象信息添加到容器里面
bookfile2 << endl
<< b.name << " " << b.writer << " " << b.press << " " << b.number << " " << b.date << " " << b.price << " " << b.temp; //由临时对象输出给文件
cout << "是否继续?" << endl
<< "1-------继续" << endl
<< "保存并返回主菜单---------2" << endl;
int back;
cin >> back;
if (back == 2)
{
cout << "正在更新..." << endl
<< endl;
show(v);
goto part1;
}
if (back == 1)
{
goto part2;
}
}
if (t == 1) //这个是以文件的方式添加图书
{
cout << "请输入要增添的图书目录" << endl;
string add2; //用于存放入要增添的图书目录
cin >> add2; //E:\\code\\book2.txt
ifstream infile2(add2, ios::in); //以只读打开文件,用于输入给对象
ofstream bookfile2(add, ios::app); //以添加打开book文件,用于输出给文件
if (!bookfile2)
{
cerr << "open erro!" << endl;
exit(1); //非正常,退出程序;
}
for (int n = 0; !infile2.eof(); n++) //把文件里的信息输入给对象b,并传给容器v,并由b输入出给文件;
{
string temp11;
infile2 >> b.name >> b.writer >> b.press >> b.number >> b.date >> b.price >> b.temp;
v.push_back(b);
bookfile2 << endl
<< b.name << " " << b.writer << " " << b.press << " " << b.number << " " << b.date << " " << b.price << " " << b.temp;
}
infile2.close();
bookfile2.close();
cout << "正在更新..." << endl
<< endl;
show(v);
goto part1; //回主菜单
}
}
if (c != 1 && c != 2 && c != 3 && c != 4)
{
cout << "erro!!" << endl;
exit(0);
}
system("pause");
}
0 条评论