图书信息管理系
2008-12-30
姓名:黄琴 学号:06440103 班级:信管061
一:需求分析:
因近几年学校对大学生的扩招,相应专业种类的增加,学校对相关于专业方面的图书需求量增大。图书馆对图书的库存量也相应增多。由老式的由图书管理员进行人工对图书入库,借出等操作,工作量相当大,就目前情况来看,图书管理员几乎不可能及时完成工作。所以学校决定开发一个图书信息管理系统,协同图书管理员的工作,这样管理员不必花太多时间用于整理图书,而可以集中精力做其他更重要的图书管理工作。减少管理员的工作负担。
学校要求本系统具体能实现的功能要求如下:
图书信息的录入、查询、修改、删除、排序、输出。图书信息可写入文件,也可从文件中读取。
结合本校的实际情况并经认真分析,为此我将其分成两个模块,由两个类实现:
1》 Book类。主要封装了图书信息。
Book类的数据成员有:
bookID(string,图书编号),
bookName(string,图书名),
publish(Publish,出版社),
author(string,图书作者),
version(int,图书版本),
count(int,图书册数)。
2》 Publish类。主要封装了出版社信息。
Publish类的数据成员:
pTime(string(yyyy-mm-rr),出版时间),
address(string,出版社地址),
pName(string,出版社名称)
数据存储方式:数组
输入:用户根据自己的需要,选择序号进行操作
输出:经系统内部的一系列处理,将最终结果显示给用户 。

本系统的具体流程图如下:
二:详细设计与实现:
1》本系统主要抽象乘两个类Book 与 Publish。他们之间的关系如下:

2》 该应用共有五个文件,两个头文件,三个源文件:

————对Book的具体实现
————主函数
————对Publish的具体实现
————对Book类的声明
————对Publish类的声明
3》
本系统设计的主要思想是:书架思想。后面将会详细介绍书架原理。主要是考虑到内存利用率的问题。
Book.h 源程序如下:
#include<iostream>
#include<string>
#include"publish.h"
using namespace std;
#ifndef BOOK_H
#define BOOK_H
class Book
{
private:
string bookID;//书的编号,不同的书不同的编号
string bookName;//书的名称
string author;//书的作者
string bookType;//书的类型
Publish *publish;//声明一个指针类
int version;//书的版本号
int count ;//该书的册数
public:
Book();//无参构造函数
void set_bookID(string id);//设置书的编号
string get_bookID();//获取书的编号
void set_bookName(string name);//设置书名
string get_bookName();//获取书名
void set_author(string author);//设置书作者
string get_author();//获取书的作者
void set_bookType(string type);//设置书的类型
string get_bookType();//获取书的类型
void set_publish(Publish &publish);//设置出版社信息
Publish get_publish();//获取出版社信息
void set_version(int version);//设置书的版本
int get_version();//获取书的版本号
void set_count(int count);//设置书的册数
int get_count();//获取书的册数
void addInfo();//录入相关图书信息
bool searchInfo(string id);//查找相关图书信息
void modifyInfo(string id);//修改相关图书信息
friend void sortInfo(Book book[],int n);//对相关图书排序
void display();//输出图书信息
Book operator =(Book temp);
static int bookCount;
friend bool isContinue();//声明友原函数,判断是否继续操作
};
#endif
Publish.h 源程序如下:
#include<string>
using namespace std;
#ifndef PUBLISH_H
#define PUBLISH_H
class Publish
{
private:
string pTime;
string address;
string name;
public:
Publish();//无参构造函数
Publish(string time,string add,string name);//带参构造函数
void set_pTime(string time);//设置出版时间
string get_pTime();//获取出版时间
void set_address(string add);//设置出版社地址
string get_address();//获取出版社地址
void set_name(string name);//设置出版社名称
string get_name();//获取出版社名称
};
#endif
Book.cpp 的源程序如下:
#include<iostream>
#include<fstream>
#include<string>
#include"publish.h"
#include"book.h"
using namespace std;
int Book::bookCount=0;//书的总类数,不同编号的书代表一类
Book::Book()
{
bookID="1";
bookName="C++编程技术";
author="郑立";
bookType="IT类";
publish=new Publish();//动态分配,后面一定要用delete,否则容易产生内存泄露
version=1;
count=1;
}
void Book::set_bookID(string id)
{
bookID=id;
}
string Book::get_bookID()
{
return bookID;
}
void Book::set_bookName(string name)
{
bookName=name;
}
string Book::get_bookName()
{
return bookName;
}
void Book::set_author(string auth)
{
author=auth;
}
string Book::get_author()
{
return author;
}
void Book::set_bookType(string type)
{
bookType=type;
}
string Book::get_bookType()
{
return bookType;
}
void Book::set_publish(Publish &pub)
{
publish->set_pTime(pub.get_pTime());
publish->set_name(pub.get_name());
publish->set_address(pub.get_address());
}
Publish Book::get_publish()
{
return *publish;
}
void Book::set_version(int ver)
{
version=ver;
}
int Book::get_version()
{
return version;
}
void Book::set_count(int coun)
{
count=coun;
}
int Book::get_count()
{
return count;
}
void Book::display()
{
cout<<"图书编号:"<<bookID<<" "<<"图书姓名:"<<bookName<<" "<<"图书作者:";
cout<<author<<" "<<"图书类型:"<<bookType<<" "<<"出版时间:"<<publish->get_pTime();
cout<<" "<<"出版社地址:"<<publish->get_address()<<" "<<"出版社名称:";
cout<<publish->get_name()<<" "<<"版本号:"<<version<<" "<<"册数:"<<count<<endl;
}
void Book::addInfo()
{
char choice;
cout<<"输入数据按Y,退出按N"<<endl;
cin>>choice;
if(choice=='Y')
{
string id;
string name;
string author;
string type;
string ptime;
string pname;
string address;
Publish publish;
int version;
int count;
cout<<"请输入图书编号:"<<endl;
cin>>id;
set_bookID(id);
cout<<"请输入图书名称:"<<endl;
cin>>name;
set_bookName(name);
cout<<"请输入图书作者:"<<endl;
cin>>author;
set_author(author);
cout<<"请输入图书类型:"<<endl;
cin>>type;
set_bookType(type);
cout<<"请输入出版时间:"<<endl;
cin>>ptime;
publish.set_pTime(ptime);
cout<<"请输入出版社地址:"<<endl;
cin>>address;
publish.set_address(address);
cout<<"请输入出版社名称:"<<endl;
cin>>pname;
publish.set_name(pname);
cout<<"请输入版本号:"<<endl;
cin>>version;
set_version(version);
cout<<"请输入册数:"<<endl;
cin>>count;
set_count(count);
cout<<endl;
bookCount++;//总数加1
}
}
bool Book::searchInfo(string id)
{
bool flag=true;
if(get_bookID()==id)
flag=true;
else
flag=false;
return flag;
}
void Book::modifyInfo(string id)
{
int choice;//所做的选择
string name,author,type,time,pname,address;
int version,count;
cout<<"请按序号输入你想修改的项目:"<<endl;
cout<<"1:图书姓名 2:图书作者 3:图书类型 4:图书版本 "<<endl;
cout<<"5:图书册数 6:出版日期 7:出版社名称 8:出版社地址 "<<endl;
cin>>choice;
if(choice!=0)//当choice=0时表示退出操作
{
if(choice==1)
{
cout<<"请输入新的名称:"<<endl;
cin>>name;
set_bookName(name);
}
else if(choice==2)
{
cout<<"请输入新的作者名:"<<endl;
cin>>author;
set_author(author);
}
else if(choice==3)
{
cout<<"请输入新的图书类型:"<<endl;
cin>>type;
set_bookType(type);
}
else if(choice==4)
{
cout<<"请输入新的版本号:"<<endl;
cin>>version;
set_version(version);
}
else if(choice==5)
{
cout<<"请输入新的册数"<<endl;
cin>>count;
set_count(count);
}
else if(choice==6)
{
cout<<"请输入新的出版时间:"<<endl;
cin>>time;
publish->set_pTime(time);
}
else if(choice==7)
{
cout<<"请输入新的出版名称:"<<endl;
cin>>pname;
publish->set_name(pname);
}
else
{ cout<<"请输入新的出版社地址:"<<endl;
cin>>address;
publish->set_address(address);
}
}
}
void sortInfo(Book book[],int n)
{ int flag;
Book temp;//临时变量
for(int i=0;i<n-1;i++)
{
//如果前一种书的编号比后一种书的编号大,则flag返回正数
flag =book[i].get_bookID().compare(book[i+1].get_bookID());
if(flag)//如果flag为正数,就交换这两种书的位置
{
temp=book[i];
book[i]=book[i+1];
book[i+1]=temp;
}
}
}
Book Book::operator =(Book temp)//重载=运算符,进行深拷贝
{
set_bookID(temp.get_bookID());
set_bookName(temp.get_bookName());
set_bookType(temp.get_bookType());
set_author(temp.get_author());
set_version(temp.get_version());
set_count(temp.get_count());
set_publish(temp.get_publish());
return *this;
}
bool isContinue()
{
char choice;
cout<<"是否继续操作(Y/N)?"<<endl;
cin>>choice;
if(choice=='Y')
return true;
else
return false;
}
Publish.cpp的源程序如下:
#include<iostream>
#include<string>
#include"publish.h"
using namespace std;
Publish::Publish()
{
pTime="2008-12-27";
address="北京";
name="清华大学出版社";
}
Publish::Publish(string time,string add,string name)
{
pTime=time;
address=add;
name=name;
}
void Publish::set_pTime(string time)
{
pTime=time;
}
string Publish::get_pTime()
{
return pTime;
}
void Publish::set_address(string add)
{
address=add;
}
string Publish::get_address()
{
return address;
}
void Publish::set_name(string nam)
{
name=nam;
}
string Publish::get_name()
{
return name;
}
主函数源程序如下:
#include<iostream>
#include<string>
#include"book.h"
#include"publish.h"
using namespace std;
void main()
{
int choice;
int i;
int n;
Book *book;//动态创建对象数组
cout<<" 欢迎进入图书信息系统! "<<endl;
cout<<"请输入你想加入的书的总类数:";
cin>>n;
cout<<endl;
cout<<"============================================================"<<endl;
cout<<"请根据序号选择相关操作"<<endl;
cout<<"============================================================"<<endl;
cout<<endl;
cout<<" 1:录入图书信息!"<<endl;
cout<<" 2:查询图书信息!"<<endl;
cout<<" 3:修改图书信息!"<<endl;
cout<<" 4:对图书排序!"<<endl;
cout<<" 5:删除图书信息!"<<endl;
cout<<" 6:输出图书信息!"<<endl;
cout<<" 7:退出系统!"<<endl;
cout<<"============================================================"<<endl;
book=new Book[n];
cin>>choice;
cout<<endl;
while(choice!=0)
{
if(choice==1)
{
for(i=0;i<n;i++)
{
cout<<"第"<<i<<"种书:"<<endl;
book[i].addInfo();
}
}
else if(choice==2)
{
string id;
cout<<"请输入你想查找的图书编号:";
cin>>id;
for(i=0;i<n;i++)
{
if(book[i].searchInfo(id))
book[i].display();
}
}
else if(choice==3)
{
string id;
cout<<"请输入你想修改的图书编号:";
cin>>id;
for(i=0;i<n;i++)
{
if(book[i].get_bookID()==id)
book[i].modifyInfo(id);
}
}
else if(choice==4)
{
sortInfo(book,n);
}
else if(choice==5)
{
string id;
cout<<"请输入你想删除的图书编号:";
cin>>id;
for(i=0;i<n;i++)
if(book[i].get_bookID()==id)
{
int temp;
temp=i;
for(int j=i+1;j<n;j++)
{
book[temp]=book[j];
temp=j;
}
n--;//删除了一种数,就减少了一种。
}
}
else if(choice==6)
{
for(i=0;i<n;i++)
book[i].display();
}
else
{
exit(1);
break;
}
if(isContinue())//选择是否继续操作
{
cout<<"请根据序号选择操作:";
cin>>choice;
}
else break;//否则退出系统
}
return ;
}
三:调试与运行:
主页面:

运行结果:
1》录入图书信息:



2》查询图书信息:

3》修改图书信息:


当然你可以继续修改,这里就不演示了。
4》对图书排序:

5》删除图书:

6》输出所有图书信息:

分析:
我们可以看到,第一个图书编号没有,因为我在前面把它删除了,所有的值设置为空,
而编号3,与编号1的图书的位置已经变了,因为我在前面对它们排了序。如果编号2没有删除,应该排在最前面。
7》退出系统:

上面是最终结果,当然在真正的设计过程中是遇到许多问题的,下面我挑几个典型的来分析:
1》
刚开始我在主函数中使用了以下代码:
else if(choice==5)
{
string id;
cout<<"请输入你想删除的图书编号:";
cin>>id;
for(i=0;i<n;i++)
if(book[i].get_bookID()==id)
book[i].deleteInfo();
}
而在book.cpp中的:
void Book::deleteInfo()
{
delete this;
}
结果当我进行序号5 操作时,出现以下错误。

产生了断言错误。产生错误的原因是,我这里的book数组并不是采用动态分配内存的方式,所以不能用delete 。而 this 是指针类型。我所采用的方法是:将book中的所有数据成员的值设置为空,即在deleteInfo中调用了一个reset函数。但存在一个问题是:尽管book对象中的值为空了,但并为真正从内存中删除。而我考虑的是假设这是一个书架,我把原先不要的图书搬走,这个书架空了。但以后还会有新书来,到时我就可以利用这个空书架放新书,而不用有多放一个书架,那样反而浪费了资源(内存)。
2》
我是用数组来存储本系统的数据的,我开始在为book对象数组分配内存时,犯了一个错误:
先看主函数中正确的声明:
const int n=3;//书的总类型,声明为常量
void main()
{
int choice;
int i;
//cout<<"请输入你想加入的书的总类数:";
// cin>>n;
Book book[n];//动态创建对象数组
在看我刚开始的:
void main()
{
int n;
cin>>n;
Book book[n];
}
我们知道,此时的n是一个变量,是一个为确定的值,有怎么可以为数组分配内存呢?
四:设计小结与心得:
1:
建议:在进行选择操作时,如果你希望执行完一段程序后继续返回到前面的操作,从新选择操作,最好用if ……else if 。switch语句并不是到处都可以用的。如果用了switch,运行完一段程序后,你会没有继续选择操作的机会,接下来出现
系统将强制你退出系统。
比如我主函数中的那段选择程序。我试着使用过switch,就出现以上情况。当我刚开始选择了序号1操作,执行完后没有出现预期的提示我是否继续选择其他序号操作,而是强制退出。
2:
还有就是关于指针的问题,能不用指针时就尽量不要用,尽管指针有很多有点,可以让程序的执行效率更搞,但如果你没有那个能耐操纵它,就不要用,不要到时适得其反,造成内存泄露。毕竟我们现在使用的应用系统并不大,用了指针其高效率的有点也体现不出来。
3:
如果你觉得用动态分配(new)内存给了你自由发挥的空间,那么建议在使用了new之后,千万别忘了还要使用delete,否则同样会造成内存泄露的问题。如以下错误:

程序应用小,可能你不太在意,但如果在大的系统开发中,很可能造成你的整个系统瘫痪,到时不仅仅好是你的程序不能运行,给公司带来的损失你恐怕还赔不起。所以一定要慎重使用new,可以不用new的地方尽量不用new,用了new就一定不要忘了使用delete。
posted on 2009-01-11 16:59
黄琴 阅读(1104)
评论(0) 编辑 收藏 引用 所属分类:
C++