实验要求
实验目的:
1、能够综合运用面向对象程序设计方法,设计实现一个相对完整信息管理应用
程序。 2、能够适当进行题目分析、实验设计、核心代码描述、实验结果分析等。
实验 7-1:设计并编写一个 C++风格应用程序,模拟一个图书管理系统应用程序,
支持系统用户的图书借阅、图书管理、用户管理等功能。图书借阅管理主要包括
图书借阅、图书归还、借阅信息查看等功能。图书管理主要包括图书的增加、删 除、修改、查看、统计等功能。用户管理主要包括用户注册、登录、修改密码、
修改个人信息、设置用户类型等功能。
具体要求:
1、定义图书管理系统中的 Book 书目类(还可以定义 User 用户类、Log 图书借 还日志类等)。 2、合理应用类的继承性进行馆藏资源的继承性定义,可分为书、碟片、电子资
源等(或将系统用户分为读者、图书管理员、系统管理员)。 3、根据不同类型用户,登录系统显示不同的用户功能菜单,实现不同的操作处
理,如学生与教师所借阅书的数量和天数均不相同(或考虑图书馆中多种馆藏资
源支持的用户操作有所区别)。 4、增加异常处理,在借阅图书时,已到所能借阅图书数量的最大数量给予提示;
归还图书时,图书已超期需要缴纳罚款。 5、通过重载运算符“<<”和“>>”方便图书信息、读者信息录入等操作,并实
现将馆藏图书信息、借阅记录等保存到磁盘,形成图书借还日志文件。 6、扩展实验:可尝试使用 MFC 可视化界面提高用户操作方便性和友好性。
实验报告
1.实验题目分析
本实验要求用c++设计一个图书管理系统程序来实现读者及管理员的各种操作。
题目分析和设计如下:
(1)读者分为学生和老师,主要包括注册、登录、查询图书、借书、还书、查询借阅信息、修改密码等操作,区别在于注册时的类型选择和可以借阅图书的最大数量(教师为20本,学生为10本)和时间(教师为60天,学生为30天),借书不能超出最大数量,超过规定期限则要罚款。
(2)管理员分为图书管理员和系统管理员。图书管理员可以进行的操作有增加图书、修改图删除图书、查询图书、统计图书和修改密码。系统非管理员可以进行的操作有增加读者、删除读者、增加图书管理员、删除图书管理员、修改读者权限、修改图书管理员权限、修改用户密码、修改图书管理员密码。
(3)定义基类Book书目类、User用户类和Log图书借还日志类。派生类Reader读者类(派生自Book、User和Log)、Librarian图书管理员类(派生自User和Log,默认一个图书管理员用户名为li密码为1234)、Administrator系统管理员类(派生自User和Log,默认一个系统管理员用户名为ann密码为1234)。Book类用于记录书籍的编号、书名、作者、出版社、在图书馆中的位置、结束时间、是否借出、结束期限等各种基本信息,进行获取当前时间、输入书籍信息和输出书籍信息等操作。User类用于记录用户名、密码和用户类型(读者、图书管理员、系统管理员),并进行密码的修改和用户类型判断等操作。Log类用于进行用户的登录和注册、判断是否登录成功并保存信息,同时将注册成功的用户信息存储到user类里。Librarian类、Reader类和Administrator类分别用于进行图书管理员、读者和系统管理员的各种操作。
2.实验设计
(1)类图
(2)代码基本功能及结构图
3.核心代码
#include<iostream>
#include<string>//字符串头文件
#include<iomanip>//控制数据输出格式
#include<fstream>//文件流
#include<time.h>//时间输出
using namespace std;
class Book{
protected:
string id;//编号
string title;//书名
string author;//作者
string press;//出版社
string location;//位置
string time;//借书时间
bool Is_Lend;//是否借出
int deadline;//借书天数
public:
Book(string i,string t,string a,string p,string l){
id=i;
title=t;
author=a;
press=p;
location=l;
Is_Lend=0;
Book_Number++;
};
Book(){
Is_Lend=false;}
bool Is_teacher;
static int Book_Number;
void SetId(string id1){
id=id1;}
void SetTitle(string title1){
title=title1;}
void SetAuthor(string author1){
author=author1;}
void SetPress(string press1){
press=press1;}
void SetLocation(string location1){
location=location1;}
void SetDeadline(int a){
deadline =a;}
void SetTime(string a){
time =a;}
void SetIs_Lend(bool a){
Is_Lend =a;}
string Gettime(){
return time;}
string GetId(){
return id;}
string GetTitle(){
return title;}
string GetAuthor(){
return author;}
string GetPress(){
return press;}
int GetDeadline(){
return deadline;}
string GetLocation(){
return location;}
bool GetIs_Lend(){
return Is_Lend;}
void show();
friend const std::string getTimeNow();
friend istream& operator >> (istream &stream,Book &b);//重载操作符>>
friend ostream& operator << (ostream &stream,Book &b);//重载操作符<<
};
int Book::Book_Number=0;
void Book::show(){
cout<<"编号:"<<setw(10)<<GetId()
<<" 书名:"<<setw(15)<<GetTitle()
<<" 作者:"<<setw(10)<<GetAuthor()
<<" 出版社:"<<setw(20)<<GetPress()
<<" 位置:"<<setw(20)<<GetLocation()
<<" 借书时间:"<<setw(10)<<Gettime()
<<" 借书期限:"<<GetDeadline()<<"天"<<endl;
}
const string getTimeNow(){
//获取当前时间
time_t t;
struct tm * lt;
time (&t);
lt = localtime (&t);//转为时间结构
char date[60] = {
0};
sprintf(date, "%d-%02d-%02d %02d:%02d:%02d",
(int)lt->tm_year + 1900,(int)lt->tm_mon + 1,(int)lt->tm_mday,
(int)lt->tm_hour,(int)lt->tm_min,(int)lt->tm_sec);
return string(date);
}
ostream &operator << (ostream &stream,Book &b){
stream<<"编号:"<<setw(10)<<b.id
<<" 书名:"<<setw(15)<<b.title
<<" 作者:"<<setw(10)<<b.author
<<" 出版社:"<<setw(20)<<b.press
<<" 位置:"<<setw(20)<<b.location<<endl;
return stream;
}
istream &operator >> (istream &stream,Book &b){
cout<<"请输入编号:";
stream>>b.id;
cout<<"请输入书名:";
stream>>b.title;
cout<<"请输入作者名:";
stream>>b.author;
cout<<"请输入出版社:";
stream>>b.press;
cout<<"请输入位置:";
stream>>b.location;
return stream;
}
static string LogName;
class User{
protected:
string name;//用户姓名
string key;//用户密码
bool Is_Admin,Is_Librarian,Is_Reader;//用户类型
public:
void key_change(User *U);//修改用户密码
int Judge();//判断用户类型
static int User_Number;
User(){
Is_Admin=0;Is_Librarian=0;Is_Reader=1;};//默认读者类型
void Setname(string name1){
name=name1;};
void Setkey(string key1){
key=key1;};
void SetIdentity(bool ad,bool li,bool re )//设置用户类型
{
Is_Admin=ad;Is_Reader=re;Is_Librarian=li;}
string Getname(){
return name;}
string Getkey(){
return key;}
bool GetisAd(){
return Is_Admin;}
bool Getisli(){
return Is_Librarian;}
bool Getisre(){
return Is_Reader;}
};
int User::User_Number=0;
void User::key_change(User *U){
int find=0;string key,key1;
for(int i=0;i<User::User_Number;i++){
if(U[i].Getname()==LogName){
find=i;break;
}
}
cout<<"请输入原密码:";
cin>>key;
if(key==U[find].Getkey()){
cout<<"请输入新密码:";
cin>>key;
cout<<"再输入一次新密码:";
cin>>key1;
if(key==key1){
U[find].Setkey(key);
cout<<"修改成功!"<<endl;
}
else{
cout<<"两次密码输入不一致,修改失败!"<<endl;}
}
else{
cout<<"密码错误!"<<endl;}
}
int User::Judge(){
if(Is_Librarian==1)return 5;
else if(Is_Admin==1)return 6;
else return 7;
};
class Log{
public:
User tp;//存储登陆成功的用户的信息
int number;//存储当前用户信息对应的User类中下标值
void Login(User *p);//登录
void SignIN(User *p);//注册
Log(){
number=0;};
bool Is_Log;//判断是否登录成功
};
void Log::SignIN(User *p){
int f1;string a,b,bb;
while(1){
f1=1;
cout<<"请输入用户名:";
cin>>a;
for(int i=0;i<=User::User_Number;i++){
if(p[i].Getname()==a){
cout<<"该用户名已被注册,请重新输入!"<<endl;f1=0;
}
}
if(f1==0){
};
if(f1==1) {
break;}
}
while(1){
cout<<"请输入密码:";
cin>>b;
cout<<"再次输入密码:";
cin>>bb;
if(bb!=b){
cout<<"两次密码不一致,请重新输入."<<endl;
}
if(bb==b){
break;
}
}
//将注册成功的用户信息存储到user类里。
(p+User::User_Number)->Setname(a);
(p+User::User_Number)->Setkey(b);
(p+User::User_Number)->SetIdentity(0, 0, 1);
tp.Setname(a);
number=User::User_Number;
User::User_Number++;
};
void Log::Login(User *p){
string a,b;int flag=0;
cout<<"请输入账号:"<<endl;
cin>>a;
cout<<"请输入密码:"<<endl;
cin>>b;
for(int i=0;i<User::User_Number;i++){
if(a==p[i].Getname()&&b==p[i].Getkey()){
tp.SetIdentity(p[i].GetisAd(), p[i].Getisli(), p[i].Getisre());
flag=1;tp.Setname(a);tp.Setkey(b);number=i;break;
}
}<