程序设计实训报告
一,实验目的
独立自主完成一个综合性编程设计命题,培养和训练应用编程解决分析和解决问题的能力。
二,实验题目
图书借阅管理
三,实验结果
四,程序代码
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<fstream>
#include <algorithm>
using namespace std;
class Book //书籍类
{public:
Book() //无参构造函数
{ borrow_flag = false;
} //下行是有参构造函数
Book(string bookName, int bookNum, string bookAuthor,string bookLocation) { borrow_flag = false;
}
void setReader(string reader,string lcn, string data); //设置读者
void setInfo(string bookName, int bookNum, string bookAuther,string bookLocation); //设置书籍信息
string getbookName()
{ return bookName;
}
int getNum()
{ return bookNum;
}
string getReader()
{ return reader;
}
bool getBorrow_flag()
{ return borrow_flag;
}//判断书籍是否借出,bool为布尔型用作逻辑判断
void setBorrow_flag(bool b)
{ borrow_flag = b;
}
void bookshow(); //显示数据信息
string bookName; //书名
int bookNum; //编号(唯一标示)
string bookAuthor; //作者
string bookLocation;
bool borrow_flag;
string reader; //读者
string lcn; //借书证号
string data; //借书日期
};
void Book::setReader(string reader,string lcn, string data)
{ borrow_flag = true;
this->reader.assign(reader);
this->lcn.assign(lcn);
this->data.assign(data);
}
void Book::setInfo(string bookName, int bookNum, string bookAuthor,string bookLocation)
{ this->bookName.assign(bookName);
this->bookNum=bookNum;
this->bookAuthor.assign(bookAuthor);
this->bookLocation.assign(bookLocation);
}
void Book::bookshow()
{ cout<<"书籍名称:"<<"《"<<bookName<<"》"<<endl;
cout<<"作者: "<<bookAuthor<<endl;
cout<<"书籍编号:"<<bookNum<<endl;
cout<<"书籍位置:"<<bookLocation<<endl;
if(borrow_flag)
{ cout<<"读者姓名:"<<reader<<endl;
cout<<"借书证号:"<<lcn<<endl;
cout<<"借书日期:"<<data<<endl;
}
else
cout<<"书籍未被借出"<<endl;
}
class Library
{ public://书籍库
Library();
void addBook(); //向图书馆里加书籍
void deleteBook(); //删除无用书籍
void borrowBook(); //借书,之前先判断书籍是否存在
void returnBook(); //还书
void getReader(); //查询某编号的书是谁借了
void checkBook();//检索图书
void sortBook();//图书排序
int searchNum(int bookNum); //根据编号得到书在数组中的下标
vector<Book> getBooks()
{ return books;
}
void showInfo();//展现所有书籍信息
void Save();//存入书籍文件
int getTotalBooks()
{ return (currentNum + borrowNum);
}
private:
vector<Book> books;//所有书籍
map<string, int> readers; //存储读者及其所借的书籍数目
int currentNum; //库存书籍数目(不包括借出的)
int borrowNum; //借出书籍数目
};
bool cmpBybookNum(Book a,Book b)
{ return a.bookNum<b.bookNum;
}
Library::Library()
{ currentNum = 0;
borrowNum = 0;
int AllBook;
AllBook=books.size();
ifstream fin("books.txt");
if(fin)
{ fin>>AllBook;
for(int i=0; i<AllBook; i++)
{ Book b;
fin>>b.bookName>>b.bookAuthor>>b.bookNum>>b.bookLocation;
fin>>b.borrow_flag;
if(b.borrow_flag)
{ fin>>b.reader>>b.lcn>>b.data;
}
books.push_back(b);
}
fin.close();
}
}
void Library::sortBook()//书籍排序
{ sort(books.begin(),books.end(),cmpBybookNum);
}
void Library::Save() //存入书籍文件
{ ofstream fout("books.txt");
if (fout)
{ fout<<books.size()<<" ";
for (int i = 0; i <(int)books.size(); i++)
{ fout<<books[i].bookName<<" "<<books[i].bookAuthor<<" "<<books[i].bookNum<<" "<<books[i].bookLocation<<" "<<books[i].borrow_flag<<" ";
if(books[i].borrow_flag)
{
fout<<books[i].reader<<" "<<books[i].lcn<<" "<<books[i].data<<" ";
}
}
fout.close();
}
}
void Library::showInfo()
{ if(books.size()<1)
{ cout<<"目前馆内并无图书!"<<endl;
system("pause");
system("cls");
}
else
{ cout << "*****所有图书信息******\n\n";
for (int i = 0; i < books.size(); i++)
{ cout << "第" << i + 1 << "本书籍的信息。" << endl;
books[i].bookshow();
cout<<"\n";
}
system("pause");
system("cls");
}
}
int Library::searchNum(int bookNum)
{ int i;
for (i = 0; i < books.size(); i++)
{ if (books[i].getNum() == bookNum)
return i;
}
return -1;
}
void Library::addBook()
{ int bookNum;
string bookName,bookAuthor,bookLocation;
int Instruct;
Book b;
cout << "********增加界面*************\n\n";
do
{ cout<<"请输入书籍名称: "<<endl;
cin>>bookName;
cout<<"请输入书籍作者:"<<endl;
cin>>bookAuthor;
cout<<"请输入书籍编号:"<<endl;
cin>>bookNum;
cout<<"请输入书籍位置:"<<endl;
cin>>bookLocation;
b.setInfo(bookName,bookNum,bookAuthor,bookLocation);
if(searchNum(bookNum)==-1)
{ books.push_back(b);
currentNum++;
cout<<"\n添加成功"<<endl;
cout<<"输入1继续添加书籍,输入2退出\n";
cin>>Instruct;
}
else
{ cout<<"已存在该编号的书籍,添加失败。\n"<<endl;
cout<<"输入1重新添加书籍,输入2退出";
cin>>Instruct;
}
}while(Instruct==1);
system("pause");
system("cls");
}
void Library::deleteBook()
{ int bookNum,index;
int Instruct;
Book b;
cout << " *****删除界面*****\n\n";
do
{ cout<<"输入要删除的书籍编号";
cin>>bookNum;
index=searchNum(bookNum);
if(index!=-1)//删除信息(具体)
{ if(!books[index].getBorrow_flag())
{ cout<<"删除的书籍信息\n";
books[index].bookshow();
books.erase(books.begin() + index);
currentNum--;
cout<<"删除成功。"<<endl;
cout<<"输入1继续删除书籍,输入2退出";
cin>>Instruct;
}
else
{ cout<<"此书籍已被借出,删除失败"<<endl;
cout<<"输入1继续删除书籍,输入2退出";
cin>>Instruct;
}
}
else
{ cout<<"删除失败,未找到编号为"<<bookNum<<"的书籍。"<<endl;
cout<<"输入1继续删除书籍,输入2退出";
cin>>Instruct;
}
}while(Instruct==1);
system("pause");
system("cls");
}
void Library::borrowBook()
{ int bookNum,index;
cout<<"******借阅界面***************\n\n";
cout<<"输入要借阅的书籍号:\n";
cin>>bookNum;
index=searchNum(bookNum);
if(index==-1)
{ cout<<"查无此书"<<endl;
system("pause");
system("cls");
}
else
{ if(books[index]. getBorrow_flag())
{ cout<<"借阅失败,书籍已被借出\n";
system("pause");
system("cls");
}
else
{ string reader, data;
string lcn;
cout << "输入读者姓名,借书证号,借书日期:\n";
cin >> reader >> lcn >> data;
if(readers[reader]!=3)
{ cout<<"要借的书籍信息\n";
books[index].bookshow();
books[index].setReader(reader,lcn,data);
cout<<"借阅完成";
currentNum--;
borrowNum++;
readers[reader]++;
system("pause");
system("cls");
}
else
{ cout<<"借书失败!该读者已借超过三本书籍!\n";
system("pause");
system("cls");
}
}
}
}
void Library::returnBook()
{ int bookNum,index;
cout << "*********还书界面************\n\n";
cout<<"请输入还书编号:\n";
cin>>bookNum;
index=searchNum(bookNum);
if(index!=-1)
{ if(books[index].getBorrow_flag())
{ cout<<"要还的图书信息为:\n";
books[index].bookshow();
books[index].setBorrow_flag(false);
currentNum++;
borrowNum--;
readers[books[index].getReader()]--;
cout<<"还书成功!\n";
system("pause");
system("cls");
}
else
{ cout<<"书籍未被借出"<<endl;
system("pause");
system("cls");
}
}
else
{ cout<<"还书失败!请检查书籍编号是否输入错误!\n";
system("pause");
system("cls");
}
}
void Library::checkBook()
{ cout<<"*****检索界面***********\n\n";
cout<<"请输入书籍名:\n"<<endl;
string word;
int flag=0;
int index=0;
int i;
int z=books.size();
cin>>word;
for(i=0;i<z;i++)
{ if(word==books[i].getbookName())
{ flag=1;
index=i;
break;
}
};
if(flag)
{ books[index].bookshow();
system("pause");
system("cls");
}
else
{ cout<<"检索失败!"<<endl;
system("pause");
system("cls");
}
}
void Library::getReader()
{ int bookNum ,index;
cout << " *****查询界面********\n\n";
cout << "输入要查找的书籍编号:";
cin >> bookNum;
index = searchNum(bookNum);
if (index != -1)
{ if (books[index].getBorrow_flag())
{ books[index].bookshow();
cout << "读者为:" << books[index].getReader() << endl;
}
else
{
books[index].bookshow();
cout << "无读者。" << endl;
}
system("pause");
system("cls");
}
else
{ cout << "查询失败,请检查书籍编号是否输入错误!\n";
system("pause");
system("cls");
}
}
Library L;
void option()
{ int x;
while (1)
{ cout << "__ 图书馆管理系统_______\n";
cout << "┏━━━━━━━━━━━━━┓ \n";
cout << "┃ [0]退出系统。 ┃ \n";
cout << "┃ [1]增加图书。 ┃ \n";
cout << "┃ [2]删除图书。 ┃ \n";
cout << "┃ [3]借阅图书。 ┃ \n";
cout << "┃ [4]归还图书。 ┃ \n";
cout << "┃ [5]显示图书信息。 ┃ \n";
cout << "┃ [6]查询图书。 ┃ \n";
cout << "┃ [7]检索图书。 ┃ \n";
cout << "┗━━━━━━━━━━━━━┛ \n";
cout << "输入要进行的操作:";
cout << "输入要进行的操作:";
cin >> x;
switch (x) {
case 1:
system("cls");
L.addBook();
L.Save();
break;
case 2:system("cls");
L.deleteBook();
L.Save();
break;
case 3:system("cls");
L.borrowBook();
L.Save();
break;
case 4:system("cls");
L.returnBook();
L.Save();
break;
case 5:system("cls");
L.sortBook();
L.showInfo();
break;
case 6:system("cls");
L.getReader();
break;
case 7:system("cls");
L.checkBook();
break;
case 0:
exit(1);
break;
default:
cout << "输入错误!" << endl;
system("pause");
system("cls");
}
}
}
int main()
{
option();
L.Save();
return 0;
}
笔记:
我遇到的问题有:一、一个简单但容易忽视的问题---编程时的逻辑问题。就比如借阅界面。在输入书籍编号之后,要分书籍编号是否正确的情况,要分是否书籍借出的情况,又要分读者是超额借出的情况;要站在使用者的角度编写,逻辑一定要清晰。先画流程图帮我解决了这个问题。二、类的三部曲之函数调用的问题。一开始没有成功调用,后来反复查看发现是定义形参的时候出错了。三、文件的读写。读文件时数据错位,原来是文件写操作时写错了。一开始是fout<<books[i].bookName<<books[i].bookAuthor。无空格两个变量会合一,就变成一个变量了,后来修改fout<<books[i].bookName<<" "<<books[i].bookAuthor才正确存入。四、int类型数据。在调试时,如果一个int数据(如书籍编号book num)被输入字母,程序输出窗口就会死机。为了减少这种bug,基本上把所有本来的int型变量改成了sring变量,string变量包容性高。
重点是我熟悉了流文件的操作。一开始甚至忘了这个部分。后来发现文件可以让程序对图书读者信息加工处理,大大提高提高上机效率。其次我明白了修改一个已经写好的程序是很难的。我之前忘记设置借阅日期int型变量,要去book类添加,不仅如此,addBook(),deleteBook(),returnBook()等等和此变量有关的函数全部要修改,可见变量和函数之间相互关联。最后锻炼了耐心。当我们第一次写好时,30多个bug,这个时候就需要极大的耐心。不要被数量打倒,因为很多error都可能是同一个错误造成的。