帮忙看一个图书馆借还书程序,有劳各位了

时间:2021-09-26 17:51:00
   小弟才大学本科,C++学了一个学期了,感觉收获不小,期末老师出了一道上机题,要求:创建一个图书馆借还书程序,以实现借书和还书功能。每本书的最大库存为三本。教师最多能借六本书,学生最多能借四本书。
   我们小组的程序两位老师只给了4.5(满分5分),原因是结构不清晰,没有实现重用,功能不完善。今天我又重新修改了一下我们的程序,做了比较大的更改,而且加了很多注释,这是我学C/C++以来第一次认真的写上注释,不知注释是不是这么写的?还有几个考虑过的问题至今没有解决,一个是图书馆管理员如何对图书进行管理,另外一个是读者如何查询欲借图书。请各位高手帮忙看一下这个程序,可能我的程序看起来显得幼稚,但请各位对我的程序易读性、算法的合理性、注释以及能想到的各方面进行评价,你的评价对我的C++学习很重要,劳烦各位了。

源程序如下: 
­
//图书馆程序.cpp 
­//时间:2008年6月26日 
­//要求:创建一个图书馆借还书程序,以实现借书和还书功能。每本书的最大库存为三本。教师最多能借六本书,学生最多能借四本书。 
­
/* 
思路:分别创建图书类、学生类、教师类,教师类从学生类派生,继承学生类的数据成员和成员函数,实现重用。 
在学生类中设置借书函数和还书函数,以实现借还书功能。程序中努力做好人机交互。 
*/ 
­
­
#include <iostream> 
#include <string>   
using namespace std; 
­
­
class Book  //设置图书馆藏书类,用以封存图书信息 

public: 
Book(string n,int N,string p)  //图书类构造函数 
   { 
     name=n;       //设置图书书名 
     NO=N;         //设置图书库存量 
     publisher=p;   //设置图书出版社 
   } 
­
­
void display()  //display函数,以显示图书信息 

cout<<"书名:"<<name<<endl; 
cout<<"目前库存:"<<NO<<endl; 
cout<<"图书出版社:"<<publisher<<endl; 
cout<<endl; 

­
//为方便调用,以下数据全部定义为公用 
string name;        //图书书名             
int NO;            //图书库存量 
string publisher;   //图书出版社 
}; 
­
­
//创建图书馆藏书小数据库,图书序号等于该对象数组的下标 
Book book[6]=     

Book("C++ primer",3,"人民邮电出版社"), 
Book("Python核心编程",3,"人民邮电出版社"), 
Book("Writing clean code",3,"电子工业出版社"), 
Book("简体中文Solaris 10用户指南",3,"Sun Microsystems, Inc"), 
Book("《The C Programming Language》第二版",3,"机械工业出版社"), 
Book("计算机程序设计艺术第三版第一卷:基本算法",3,"国防工业出版社") 
}; 
­
­
void display_all()   //显示图书馆所有图书,方便读者借阅,暂时当作查询系统

int i; 
   
cout<<"这是图书馆的所有图书"<<endl; 
for ( i=0;i<6;i++ ) 

      cout<<"图书序号:"<<i<<endl; 
      cout<<"书名:"<<book[i].name<<endl; 
      cout<<"目前库存:"<<book[i].NO<<endl; 
      cout<<"图书出版社:"<<book[i].publisher<<endl; 
      cout<<endl; 


}   // display_all 函数结束
­
class student  // student类,用以定义学生信息 

public: 
   student(string nam , int num)  //student构造函数 
      { 
        name=nam; 
        number=num; 
      } 
­
­void borrow(int);    //定义借书成员函数   
void back(int);      //定义还书成员函数 
­
­protected: 
string name;    //学生姓名 
int number;     //在图书馆已经借了的书的数量 
}; 
­
­
class teacher:public student  //teacher类,teacher是student的派生类

public: 
teacher ( string nam , int num, string t):student(nam , num ) //派生类构造函数 

title=t;   

­
­private: 
string title;   //教师职称 
}; 
­
­
void student::borrow(int a)     //借书成员函数 

int i,j;    //定义两个整型变量,以便需要时使用 
char k;     //定义字符型变量以便进行Y/N的判断 
­
­void service();  //声明service函数 
­
if(number>=a)  //首先进行权限判断,如果读者已借图书数量不小于他的权限,则提示他不能借书了 

cout<<"根据您的权限,你最多能借"<<a<<"本书!您现在不能借书欢迎下次再来"<<endl; 
cout<<"您是否想进行其他操作?(是请输入y,退出请输入n)"<<endl;      //不能借书了,提示进行其他操作
cin>>k; 
   if(k==121) 
      service();   //输入y,则进行其他操作,调用service函数,service函数将在后面定义
   if(k==121) 
      return;      //调用完service函数,退出借书函数
   else if(k=110) 
      return;    //不进行其他操作,则退出借书函数
   cout<<endl; 

else   //读者有权借书,则进行以下操作

   display_all(); //调用display_all函数,显示所有图书信息(6本),方便读者借阅 
­
    cout<<"您想借哪本书? 请输入图书序号0-5"<<endl; 
   cin>>i; 
   while(book[i].NO==0 || i>5 || i<0)  //判断所要借图书的库存及输入的合法性,这里对数字判断,没有对字母判断,不强壮
    { 
        cout<<"您输入的图书序号错误或者所借书库存不足,请重新输入.图书序号是0-5"<<endl; 
        cin>>i; 
­
­        cout<<"您是否想进行其他操作?(是请输入y,继续借书请输入n)"<<endl;   //提示读者是否进行其他操作
        ­cin>>k; 
           if(k==121) 
               service();  //如果读者要进行其他操作,则调用service函数,对读者进行重新引导 
            if(k==121) 
               return;    //进行其他操作完毕,直接跳出borrow函数 
            else 
               continue;  //若读者选择继续借书,则跳出本次循环,对读者刚才输入的数字重新判断,进行下一次循环 
­
    } 
cout<<endl;    //此处还行是为了人机界面的美观 
cout<<"以下是您要借的书籍的信息"<<endl; 
­
book[i].display(); //输出读者所要借图书信息
­
cout<<"您想借几本书?"<<endl; 
cin>>j; 
­
­
//判断读者的权限、图书馆库存及输入的合法性 
while( (a-number)<j || book[i].NO<j || j<0 || j>3)   
   { 
     cout<<"因为你的权限不够、数量输入有误或者图书馆库存不足,"; 
     cout<<"你目前不能借这么多书!请输入一个合适的数目."<<endl; 
        cin>>j; 
­
­       //提示读者是否进行其他操作 
        cout<<"您是否想进行其他操作?(是请输入y,继续借书请输入n)"<<endl;   
­       cin>>k; 
          if(k==121) 
             service(); 
          if(k==121) 
             return; 
          else 
             continue; 
      cout<<endl; 
­

­
    book[i].NO=book[i].NO-j;    //借书完毕,对图书馆的小数据库重新调整一下 
      number=number+j;       //借书完毕,读者已借书籍数量要加上现在借的书数量 
    cout<<endl; 
    cout<<"您在图书馆还可以借 "<<a-number<<" 本书"<<endl;  //提示读者现有权限
    cout<<"《"<<book[i].name<<"》"<<"目前剩余"<<book[i].NO<<"本"<<endl;  //显示改本图书现有库存

}  //borrow函数结束 
­
­
­
­void student::back(int a)       //还书成员函数 

  int n,m; 
  char k; 
   
­  void service(); 
­
  cout<<"您要还哪本书"<<endl; 
  cin>>n; 
while(book[n].NO=3)  //判断图书馆库存,库存是满的,那就没人从这借过这种书而且没还 
  { 
   cout<<"您借过这本书吗?请重新输入图书序号. "<<endl; 
   cin>>n; 
   cout<<"您是否想进行其他操作?(是请输入y,继续还书请输入n)"<<endl; 
   cin>>k; 
   if(k==121) 
       service(); 
   if(k==121) 
       return; 
   else 
       continue; 
   
   cout<<endl; 
         
  } 
while(n>5 || n<0)   //判断读者所要借的书是否存在 
  { 
     cout<<"您输入的图书序号错误,请重新输入.图书序号是0-5. "<<endl; 
      cin>>n; 
     cout<<"您是否想进行其他操作?(是请输入y,继续还书请输入n)"<<endl; 
      cin>>k; 
        if(k==121) 
            service(); 
        if(k==121) 
            return; 
        else 
           continue; 
  cout<<endl; 
­
  } 
cout<<endl;    ­
­
cout<<"以下是您要借的书籍的信息"<<endl; 
book[n].display(); 
­
cout<<"你要还几本书"<<endl; 
cin>>m; 
­
­
//判断图书馆这种书的库存是否小于读者要还的书的数量,及读者输入的合法性 
while((3-book[n].NO)<m || m>3)   
­
  { 
      cout<<"您有借过这么多书吗?请重新输入."<<endl; 
       cin>>m; 
      cout<<"您是否想进行其他操作?(是请输入y,继续借书请输入n)"<<endl; 
       cin>>k; 
         if(k==121) 
            service(); 
         if(k==121) 
            return; 
         else if(k=110) 
            continue; 
   cout<<endl; 
­
  } 
  book[n].NO+=m;  //还书完毕,及时对图书馆的数据库进行整理 
  number-=m;      //读者已借书籍数减轻现在所还书籍数量 
   
  //以下是一些给读者的提示信息 
  cout<<"恭喜!您还书成功!"<<endl; 
  cout<<"你还可以借 "<<a-number<<" 本书!"<<endl; 
}//back函数结束 
­
­
­void service()    //service函数,完成对读者的服务、询问功能 

int a; 
int b; 
­
student stud("ming",0);            //定义student类的对象stu,并初始化 
teacher tea("li",0,"assistant");    //定义teacher类的对象tea,并初始化 
­
­
cout<<"欢迎来到图书馆,请问您的身份是:(请输入首数字)"<<endl; //询问读者身份,给出选项 
cout<<"1.教师"<<endl; 
cout<<"2.学生"<<endl; 
cin>>a; 
­
while(a!=1 && a!=2)          //对读者的错误输入进行提醒 

cout<<"请输入正确的选项:"<<endl; 
cin>>a; 

cout<<endl;         
­
­
cout<<"请问您想要:(请输入首数字)"<<endl;  //询问读者所希望进行的工作,给出选项 
cout<<"1.借书"<<endl; 
cout<<"2.还书"<<endl; 
cout<<"3.离开借书台"<<endl; 
cin>>b; 
while(b!=1 && b!=2 && b!=3)     //对读者的错误输入进行提醒 

cout<<"请输入正确的选项"<<endl; 
cin>>b; 

cout<<endl; 
­
­
if(a==1)          //如果读者是老师,则进行以下操作 

   if(b==1) 
     { 
     tea.borrow(6);  //调用借书函数 
     } 
   else if(b==2) 
     { 
     tea.back(6);   //调用还书函数 
     } 
   else 
     { 
     cout<<"=^_^=谢谢您的光临!\n"<<endl; //退出 
     } 

else if(a==2)    //如果读者是学生,则进行以下操作 

   if(b==1) 
     { 
     stud.borrow(4); 
     } 
   else if(b==2) 
     { 
     stud.back(4); 
     } 
   else 
     { 
     cout<<"=^_^=谢谢您的光临!\n"<<endl; 
     } 
­

cout<<endl; 
­
}  //service函数结束 
­
­
­
//主函数 
int main () 

char k; 
­
service(); //调用sercice函数
­
//操作完毕,提示读者是否进行其他操作。注意:此处是loop的开始 
loop:cout<<"是否继续进行其他操作?"; 
cout<<"(进行其他操作请输入y,继续借书请输入n)"<<endl;   
cin>>k; 
cout<<endl; 
if(k==121) 

service(); 
    goto loop;    //此处用goto进行循环,循环提示读者操作。goto到loop,上面已经提示 

else 
    cout<<"谢谢您的光临!\n"<<endl;  //退出! 
­
­
return 0; 
}  //程序结束

9 个解决方案

#1


用vc做个可视化的程序效果要好些

#2


学生类派生出老师类。这个按常理好像有点不对头吧?还有在学生类中
class student  // student类,用以定义学生信息 

public: 
  student(string nam , int num)  //student构造函数 
      { 
        name=nam; 
        number=num; 
      } 
­ 
­void borrow(int);    //定义借书成员函数  
void back(int);      //定义还书成员函数 
­ 
­protected: //定义成private更好
string name;    //学生姓名 
int number;    //在图书馆已经借了的书的数量 
}; 

#3


不错呀!顶一下!复制一下好好看看!

#4


应该有个基类,用来派生学生类和教师类

#5


teacher类和student类的设计不合理
应该设计一个people类作为他们的基类

goto循环不好, 改为while循环

#6


学了一学期 挺厉害了

#7


谢谢各位宝贵的意见,我会再做相应的更改。不知哪位老兄能提供一个思路来编个图书管理员程序以对图书馆的图书进行管理,比如增加图书、减少图书、更改图书信息,不然图书馆只有6本书是不行的啊!另外再编个读者查询系统会更好

5楼的同志:我也考虑过不使用goto循环而使用while,但是while循环的条件的是什么呢?

#8



while(1)
{
service();
cout < <"是否继续进行其他操作?"; 
cout < <"(进行其他操作请输入y,继续借书请输入n)" < <endl;  
cin>>k; 
cout < <endl; 
if(k==y||k==Y)
break;
}

#9


还有一个问题,就是输入异常的处理,比如图书序号是0-5的整数,而读者输入的是字符,想要提示读者重新输入,如何做呢?

#1


用vc做个可视化的程序效果要好些

#2


学生类派生出老师类。这个按常理好像有点不对头吧?还有在学生类中
class student  // student类,用以定义学生信息 

public: 
  student(string nam , int num)  //student构造函数 
      { 
        name=nam; 
        number=num; 
      } 
­ 
­void borrow(int);    //定义借书成员函数  
void back(int);      //定义还书成员函数 
­ 
­protected: //定义成private更好
string name;    //学生姓名 
int number;    //在图书馆已经借了的书的数量 
}; 

#3


不错呀!顶一下!复制一下好好看看!

#4


应该有个基类,用来派生学生类和教师类

#5


teacher类和student类的设计不合理
应该设计一个people类作为他们的基类

goto循环不好, 改为while循环

#6


学了一学期 挺厉害了

#7


谢谢各位宝贵的意见,我会再做相应的更改。不知哪位老兄能提供一个思路来编个图书管理员程序以对图书馆的图书进行管理,比如增加图书、减少图书、更改图书信息,不然图书馆只有6本书是不行的啊!另外再编个读者查询系统会更好

5楼的同志:我也考虑过不使用goto循环而使用while,但是while循环的条件的是什么呢?

#8



while(1)
{
service();
cout < <"是否继续进行其他操作?"; 
cout < <"(进行其他操作请输入y,继续借书请输入n)" < <endl;  
cin>>k; 
cout < <endl; 
if(k==y||k==Y)
break;
}

#9


还有一个问题,就是输入异常的处理,比如图书序号是0-5的整数,而读者输入的是字符,想要提示读者重新输入,如何做呢?