都做为字段 9.编号 作索引为
加 24.人口状况说明 用来记录人口是下面
1.常住人口明细 5.迁入人员明细
2.暂住人口登记 6.迁出人员明细
3.空挂人口登记 7.登记变更名细
4.户籍不在本辖区的配偶登记
哪种情况.
就差不多可以了.一张表就可以了.
数据统计就是查询语句了.
数据库连接(Connection)数据库连接
获取数据库连接有两种方法,一种是通过驱动程序管理器DriverManager类,另一种则是使用DataSource接口。这两种方法都提供了了一个getConnection方法,用户可以在程序中对它们进行相应处理后调用这个方法来返回数据库连接。
• DriverManager类
• DataSource接口
• Connection接口
• JDBC URL
jdbc:<subprotocol>:<subname>
• 驱动程序注册方法
(1)调用Class.forName方法
(2)设置jdbc.drivers系统属性
• DriverManager方法
DriverManager类中的所有方法都是静态方法,所以使用DriverManager类的方法时,不必生成实例。
DriverManager
• getConnection方法
作用是用于获取数据库连接,原型如下:
public static Connection getConnection(String url)
throws SQLException;
public static Connection getConnection(String url, String user, String password)
throws SQLException
public static Connection getConnection(String url, Properties info)
throws SQLException
• 使用DriverManager的getConnetion方法
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver")
Connection conn = DriverManager.getConnection
("jdbc:odbc:sqlserver", "sa", "sa")
• 使用设置jdbc.drivers系统属性的方法
java -Djdbc.drivers=sun.jdbc.odbc.JdbcOdbcDriver test.java
DataSource 接口
……
//从上下文中查找数据源,并获取数据库连接
Context ctx = new InitialContext()
DataSource ds = (DataSource) ctx.lookup("sqlserver")
Connection conn = ds.getConnection()
//查询数据库中所有记录
Statement stmt = conn.createStatement()
ResultSet rs = stmt.executeQuery("SELECT * FROM student")
……
Connection 接口
Connection接口代表了已经建立的数据库连接,它是整个JDBC的核心内容。Connnection接口中的方法按照它们所实现的功能,可以分为三类:
• 生成数据库语句
• 管理数据库事务
• 获取数据库信息
生成数据库语句
JDBC将数据库语句分成三种类型 :
• 生成Statement 语句 :
Connection.createStatement()
• 生成PreparedStatement 语句 :
Connection. prepareStatement()
• 生成CallableStatement 语句 :
Connection. prepareCall ()
管理数据库事务
• 默认情况下,JDBC将一条数据库语句视为一个完整的事务。可以关掉默认事务管理:
public void setAutoCommit(Boolean autoCommit) throws SQLException;
将autoCommit的值设置为false,就关掉了自动事务管理模式
• 在执行完事务后,应提交事务:
public void commit() throws SQLException;
• 可以取消事务:
public void rollback() throws SQLException;
第二讲 第四部分
数据库语句
数据库语句
JDBC数据库语句共有三种类型:
• Statement:
Statement语句主要用于嵌入一般的SQL语句,包括查询、更新、插入和删除等等。
• PreparedStatement:
PreparedStatement语句称为准备语句,它是将SQL语句中的某些参数暂不指定,而等到执行时在统一指定。
• CallableStatement:
CallableStatement用于执行数据库的存储过程。
Statement 语句
• executeQuery方法
• executeUpdate方法
• execute方法
• close方法
executeQuery方法
• executeQuery方法主要用于执行产生单个结果集的SQL查询语句(QL),即SELECT语句。executeQuery方法的原型如下所示:
• public ResultSet executeQuery(String sql) throws SQLException
executeUpdate方法
• executeUpdate方法主要用于执行 INSERT、UPDATE、DELETE语句,即SQL的数据 *** 作语句(DML)
• executeUpdate方法也可以执行类似于CREATE TABLE和DROP TABLE语句的SQL数据定义语言(DDL)语句
• executeUpdate方法的返回值是一个整数,指示受影响的行数(即更新计数)。而对于CREATE TABLE 或 DROP TABLE等并不 *** 作特定行的语句,executeUpdate的返回值总为零。
execute方法
execute方法用于执行:
• 返回多个结果集
• 多个更新计数
• 或二者组合的语句
execute方法
• 返回多个结果集:首先要调用getResultSet方法获得第一个结果集,然后调用适当的getter方法获取其中的值。要获得第二个结果集,需要先调用getMoreResults方法,然后再调用getResultSet方法。
• 返回多个更新计数:首先要调用getUpdateCount方法获得第一更新计数。然后调用getMoreResults,并再次调用getUpdateCount获得后面的更新计数。
• 不知道返回内容:如果结果是ResultSet对象,则execute方法返回true;如果结果是int类型,则意味着结果是更新计数或执行的语句是DDL命令。
execute方法
为了说明如果处理execute方法返回的结果,下面举一个代码例子:
stmt.execute(query)
while (true) {
int row = stmt.getUpdateCount()
//如果是更新计数
if (row >0) {
System.out.println("更新的行数是:" + row)
stmt.getMoreResults()
continue
}
execute方法
//如果是DDL命令或0个更新
if (row == 0) {
System.out.println("没有更新,或SQL语句是一条DDL语句!")
stmt.getMoreResults()
continue
}
//如果是一个结果集
ResultSet rs = stmt.getResultSet
if (rs != null) {
while (rs.next()) {
// 处理结果集
. . .
}
stmt.getMoreResults()
continue
}
break
}
PreparedStatement 语句
登录一个网站或BBS时 :
• 使用Statement语句
Statement stmt = conn.createStatement()
ResultSet rs = stmt.executeQuery
(“SELECT password FROM userinfo
WHERE id=userId")
• 使用PreparedStatement语句
PreparedStatement pstmt=conn.prepareStatement
(“SELECT password FROM userinfo
WHERE id=?")
pstmt.setString(1, userId)
PreparedStatement语句
• 常用的setter方法
public void setBoolean(int parameterIndex, boolean x) throws SQLException
public void setByte(int parameterIndex, byte x) throws SQLException
public void setShort(int parameterIndex, short x) throws SQLException
public void setInt(int parameterIndex,int x) throws SQLException
public void setLong(int parameterIndex, long x) throws SQLException
public void setFloat(int parameterIndex, float x) throws SQLException
public void setDouble(int parameterIndex, double x) throws SQLException
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException
public void setString(int parameterIndex, String x) throws SQLException
public void setBytes(int parameterIndex, byte[] x) throws SQLException
public void setDate(int parameterIndex, Date x) throws SQLException
public void setTime(int parameterIndex, Time x) hrows SQLException
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException
PreparedStatement语句
• PreparedStatement接口是由Statement接口扩展而来的,重写了executeQuery方法、executeUpdate方法和execute 方法
• public ResultSet executeQuery() throws SQLException
• public int executeUpdate() throws SQLException
• public boolean execute() throws SQLException
CallableStatement语句
• CallableStatement语句是由Connection接口的prepareCall方法创建的,创建时需要传入字符串参数,参数的形式为:
• {call procedure_name[(?, ?, ...)]}
• {? = call procedure_name[(?, ?, ...)]}
• {call procedure_name}
CallableStatement语句
• 其中的问号是参数占位符,参数共有两种:
• IN参数
• OUT参数
• IN参数使用setter方法来设置
• OUT参数则使用registerOutParameter方法来设置
CallableStatement 语句
CallableStatement cstmt = con.prepareCall
("{call getTestData(?, ?)}")
cstmt.registerOutParameter
(1, java.sql.Types.TINYINT)
cstmt.registerOutParameter
(2, java.sql.Types.DECIMAL, 3)
cstmt.executeQuery()
byte x = cstmt.getByte(1)
java.math.BigDecimal n =
cstmt.getBigDecimal(2, 3)
第二讲 第五部分
结 果 集
结果集
• JDBC为了方便处理查询结果,又专门定义了一个接口,这个接口就是ResultSet接口。ResultSet接口提供了可以访问数据库查询结果的方法,通常称这个接口所指向的对象为结果集。
• 有两种方法得到结果集,一种是直接执行查询语句,将结果存储在结果集对象上;另一种是不存储返回结果,而在需要时调用数据库语句的getResultSet方法来返回结果集
结果集
• 结果集指针
由于返回的结果集可能包含多条数据记录,因此ResultSet 接口提供了对结果集的所有数据记录轮询的方法。结果集自动维护了一个指向当前数据记录的指针,初始时这个指针是指向第一行的前一个位置。 next 方法就是用于向前移动指针的
结果集
• 结果集属性
默认情况下,结果集是一个不可更新集,并且结果集的指针也只能向前移动。也就是说,在得到了一个结果集之后,用户只能按照从第一条记录到最后一条记录的顺序依次向后读取,而不能跳到任意条记录上,也不能返回到前面的记录。不仅如此,结果集的这种轮询只能进行一次,而不能再将指针重置到初始位置进行多次轮询
结果集
• 结果集属性
类型
并发性
有效性
• 属性的设置是在生成数据库语句时通过向生成方法传入相应的参数设定的,而当结果集已经返回时就不能够再改变它的属性了。
结果集生成Statement语句共有三种方法
public Statement createStatement() throws SQLException
public Statement createStatement
(int resultSetType, int resultSetConcurrency)
throws SQLException
public Statement createStatement
(int resultSetType, int resultSetConcurrency,
int resultSetHoldability)
throws SQLException
结果集
• 生成PreparedStatement语句共有六种方法
public PreparedStatement prepareStatement(String sql) throws SQLException
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
throws SQLException
public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
throws SQLException
public PreparedStatement prepareStatement(String sql, int resultSetType,
int resultSetConcurrency)
throws SQLException
public PreparedStatement prepareStatement(String sql, int resultSetType,
int resultSetConcurrency,
int resultSetHoldability)
throws SQLException
public PreparedStatement prepareStatement(String sql. String[] columnNames)
throws SQLException
结果集
• 生成CallableStatement语句共有三种方法
public CallableStatement prepareCall(String sql)
throws SQLException
public CallableStatement prepareCall
(String sql, int resultSetType,
int resultSetConcurrency)
throws SQLException
public CallableStatement prepareCall
(String sql, int resultSetType,
int resultSetConcurrency,
int resultSetHoldability)
throws SQLException
结果集
结果集类型
• 结果集的类型共有三种,TYPE_FORWARD_ONLY类型的结果集只能向前移动指针,而TYPE_SCROLL_INSENSITIVE类型和TYPE_SCROLL_SENSITIVE类型的结果集则可以任意移动指针。后两种类型的区别在于,前者对来自其它处的修改不敏感(静态),而后者则对于别人的修改敏感(动态视图)。
结果集
结果集类型
• 对于可以任意移动指针的结果集,可以用来移动指针的方法包括:
• next 和previous :
• absolute 和relative :参数可正可负
• afterLast 、beforeFirst 、last 和first :
结果集
结果集并发性
• 结果集的并发性共有两种,CONCUR_READ_ONLY的结果集是只读而不可更新的;而CONCUR_UPDATABLE的结果集则是可以通过update方法进行更新的。
• ResultSet接口提供了一组update方法,用于更新结果集中的数据。这些方法与PreparedStatement接口中定义的setter方法一样,也是与类型相对应的。所有的update方法都以update开头 。
• 所有的update方法都有两个参数,第一个参数用于指定更新的列,它可以是列名称也可以是列的序号;第二个参数则表示将要更新列的值。
结果集
结果集并发性
• Statement stmt = conn.createStatement
•(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)
•ResultSet rs = stmt.executeQuery("SELECT * FROM student " +
• "WHERE grade=2 AND math>60 AND physics>60 AND " +
• "chemistry>60 AND english>60 AND chinese>60")
•while(rs.next()){
•rs.updateString("grade", "3")
•rs.updateRow()
•}
结果集
结果集有效性
• 结果集的有效性是指在调用了Connection 接口的commit 方法后,结果集是否自动关闭。所以它只有两个可选值,即HOLD_CURSORS_OVER_COMMIT 和CLOSE_CURSORS_AT_COMMIT 。前者表示调用commit 方法之后,结果集不关闭;而后者则表示关闭结果集。
结果结果集
• 结果集的getter方法
ResultSet接口还提供了一组getter方法,用于返回当前记录的属性值。它们都是以get开头的,后接数据类型。比如,如果要返回一个float类型的列值,则应调用getFloat方法。每一种类型的getter方法都有两种形式,它们的名称相同而参数不同。这两种形式的getter方法都只有一个参数,第一种形式的getter方法参数是String类型的,用于指定列的名称;另外一种形式的getter方法参数则是int类型的,用于指定列的序号。
高级语言程序设计(2)课程设计
一 程序设计说明书
【设计题目】 图书馆借阅管理
【问题描述】图书馆,适合用C++面向对象的功能来描述。图书馆管理系统分为借书、还书、图书管理和读者服务等四个部分。设计一个读者类Reader,记录每个读者基本信息;读者库类Rdatabase,记录所有读者信息;图书类Book, 记录每本书的基本信息;图书库类Bdatabase, 记录所有图书信息。
【基本要求】
1读者库类RDatabase中,其构造函数中,将read.txt文件中所有读入读者记录rede[]中。处理完毕,在析构函数中将read[]中的所有未删记录写入到read.txt中。
2图书库类BDatabase中,其构造函数中,将book.txt文件中所有读入图书记录book[]中。处理完毕,在析构函数中将book[]中的所有未删记录写入到book.txt中。
3 利用构造函数完成读者和图书数据初始化,完成内存分配。程序结束前,析构函数完成所申请的堆内存空间。
4 编写主函数,对所编写的矩阵类进行全面测试。要求用户界面采用菜单方式。测试中需要读者和图书数据通过I/O流从磁盘文件读入,同时显示在屏幕上。得到的数据通过I/O流写入磁盘文件保存,同时显示在屏幕上。
5 源程序中要有充分的注释,报告中要有详细的流程图和文字材料。
【类的设计】
该程序包含了四个类,如下:
1.Reader类,有读者的基本管理功能,具有以下私有数据:
int tag//删除标记 1:已删;0:未删
int no//读者编号
char name[10]//读者姓名
int borbook[Maxbor]//所借图书
2.读者库类Rdatabase, 具有以下私有数据:
int top//读者记录指针
Reader read[Maxr]//读者记录
3.图书库类Book,有一本图书的基本功能,有以下私有数据:
int tag//删除标记 1:已删;0:未删
int no//图书编号
char name[20]//书名
int onshelf//是否在架 1在架 0已借
4.图书库类BDatabase,有以下私有数据:
int top//图书记录指针
Book book[Maxb]//图书记录
【特殊函数的设计说明】
构造函数
1.Reader类中构造函数Reader(),初始化函数;
2.读者库类RDatabase中,其构造函数Rdatabase(),将read.txt文件中所有读入读者记录rede[]中。
3.Book类中构造函数Book(),初始化函数;
4.图书库类BDatabase中,其构造函数中,将book.txt文件中所有读入图书记录book[]中。
拷贝构造函数
Reader类中的拷贝构造函数将getname()的返回值读者姓名拷贝到setname()中,Book类中的拷贝构造函数将getname()函数的返回值图书名拷贝到图书名设置函数setname()中。
析构函数
1.读者库类RDatabase中,其析构函数~Rdatabase(),将read[]中的所有未删记录写入到read.txt中;
2.图书库类BDatabase中,其析构函数~Bdatabase(),将book[]中的所有未删记录写入到book.txt中。
运算符重载
重载了“=”,当比较读者编号和图书编号时,重载;重载位运算符“〈〈”和“〉〉”等。
【主要函数算法流程图】
【程序的使用方法】
1.进入 *** 作页面,按提示 *** 作;
2.首先,新增图书和读者信息,之后就可以对以存在的信息进行 *** 作;
3. *** 作当中,可以随时增加,更改和删除图书或读者信息;
4.当选择退出时,进行清屏。
二 程序上机调试报告
【语法错误及其排除】
1.在敲程序时,有很多拼写错误,例好多处把Readdata()误打Readdate();结束的分号,在不同的输入法状态下输入,这些小错误刚开始很难发现,不过有了经验,就很容易了。
2.创建新的构造函数时,使用出现了错误。重载构造函数要注意函数的访问权限,结果就不会出现错误。
【算法错误及其排除】
1.读者类中借书 *** 作函数中,采用循环语句时判断读者已借图书量时for(int i=0i<Maxbori++)误写为for(int i=1i<Maxbori++),使循环发生错误。
2.指针使用错误,指针b和r混淆,导致编译错误得到“error C2660: 'retbook' : function does not take 1 parameters”错误报告。
三 程序测试结果
【收获及体会】
除了课堂外,课程设计是最能学到东西的,最考验人的。在做课程设计这段时间,时刻都感觉自己有好多不懂,要学的太多了!经过这次课程设计,让我对C++这门语言有了更深的认识, *** 作能力有了提高。要想得到敲的代码运行出来后的满足感,需要耐心细心,毅力以及充沛的体力。只有经过多次编辑,多次编译,再多次运行,才能编写出更好的程序,有时候需要多次的更正才达到所要的运行结果。学习编程,需要多揣摩,实践,实践,再实践,编程技能才能更上一层楼,此外还得多向高手请教!
【源程序代码】
//********************
//图书馆借阅管理
//班级:
//学号:
//姓名:
//********************
#include<iostream.h>
#include<iomanip.h>
#include<string.h>
#include<fstream.h>
const int Maxr=1000//最多的读者
const int Maxb=10000//最多的图书
const int Maxbor=8//每位读者最多借8本书
class Reader //读者类
{
int tag//删除标记 1已删;0未删
int no//读者编号
char name[10]//读者姓名
int borbook[Maxbor]//所借图书
public :
Reader(){}//构造函数
char *getname(){return name}//获取读者姓名
int gettag(){return tag}//获取删除标记
int getno(){return no}//获取读者编号
void setname(char na[])//设置读者姓名
{
strcpy(name,na)
}
void delbook(){tag=1}//设置删除标记
void addreader(int n,char *na)//增加读者
{
tag=0
no=n
strcpy(name,na)
for(int i=0i<Maxbori++)
borbook[i]=0
}
void borrowbook(int bookid)//借书 *** 作
{
for(int i=0i<Maxbori++)
{
if(borbook[i]==0)
{
borbook[i]=bookid
}
}
}
int retbook(int bookid)//还书 *** 作
{
for(int i=0i<Maxbori++)
{
if (borbook[i]==bookid)
{
borbook[i]=0
return 1
}
}
return 0
}
void disp()//输出读者信息
{
cout<<setw(5)<<no<<setw(10)<<name<<"借书编号:"
for(int i=0i,Maxbori++)
if(borbook[i]!=0)
cout<<borbook[i]<<endl
}
}
class RDatabase//读者库类
{
int top//读者记录指针
Reader read[Maxr]//读者记录
public:
RDatabase()//构造函数,将reader.txt读到read[]中
{
Reader s
top=-1
fstream file("reader.txt",ios::in)
while(1)
{
file.read((char*)&s,sizeof(s))
if(!file)break
top++
read[top]=s
}
file.close()
}
void clear()//删除所有读者信息
{
top=-1
}
int addreader(int n,char *na)//添加读者,检查是否已存在
{
Reader *p=query(n)
if(p==NULL)
{
top++
read[top].addreader(n,na)
return 1
}
return 0
}
Reader*query(int readerid)//按编号查找
{
for(int i=0i<=topi++)
if(read[i].getno()==readerid&&read[i].gettag==0)
return &read[i]
return NULL
}
void disp()//删除读者所有信息
{
for(int i=0i<=topi++)
read[i].disp()
}
void readerdata()//读者库维护
~RDatabase()//析构函数,将read[]写入reader.txt文件中
{
fstream file("reader.txt",ios::out)
for(int i=0i<=topi++)
if(read[i].gettag()==0)
file.write((char*)&read[i],sizeof(read[i]))
file.close()
}
}
void RDatabase::readerdata()
{
int choice=1
char rname[20]
int readerid
Reader*r
while(choice!=0)
{
cout<<"读者服务 1新增 2更该 3删除 4查找 5显示 6全删 0退出"<<endl
cin>>choice
switch(choice)
{
case 1:
cout<<"请输入读者编号:"
cin>>readerid
cout<<"读入读者姓名:"
cin>>rname
addreader(readerid,rname)
break
case 2:
cout<<"请输入读者编号:"
cin>>readerid
r=query(readerid)
if(r==NULL)
{
cout<<"读者不存在"<<endl
break
}
cout<<"请输入新读者姓名:"
cin>>rname
r->setname(rname)
break
case 3:
cout<<"请输入读者编号:"
cin>>readerid
r=query(readerid)
if(r==NULL)
{
cout<<"读者不存在"<<endl
break
}
r->delbook()
break
case 4:
cout<<"请输入读者编号:"
cin>>readerid
r=query(readerid)
if(r==NULL)
{
cout<<"该读者编号不存在"<<endl
break
}
case 5:
disp()
break
case 6:
clear()
break
}
}
}
class Book//图书类
{
int tag//删除标记 1:已删;0:未删
int no//图书编号
char name[20]//书名
int onshelf//是否在架 1在架 0已借
public:
Book(){}
char*getname(){return name}//获取读者姓名
int getno(){return no}//获取图书编号
int gettag(){return tag}//获取删除标记
void setname(char na[])//设置书名
{
strcpy(name,na)
}
void delbook(){tag=1}//删除图书
void addbook(int n,char*na)//增加图书
{
tag=0
no=n
strcpy(name,na)
onshelf=1
}
int borrowbook()//借书 *** 作
{
if(onshelf==1)
{
onshelf=0
return 1
}
return 0
}
void retbook()//还书 *** 作
{
onshelf=1
}
void disp()//输出图书
{
cout<<setw(6)<<no<<setw(18)<<name<<setw(10)<<(onshelf==1?"在架":"已借")<<endl
}
}
class BDatabase//图书库类
{
int top//图书记录指针
Book book[Maxb]//图书记录
public:
BDatabase()//构造函数,将book.txt读到book[]中
{
Book b
top=-1
fstream file("book.txt",ios::in)
while(1)
{
file.read((char*)&b,sizeof(b))
if(!file)break
top++
book[top]=b
}
file.close()
}
void clear()//全删
{
top=-1
}
int addbook(int n,char*na)//增加图书
{
Book*p=query(n)
if(p==NULL)
{
top++
book[top].addbook(n,na)
return 1
}
cout<<"新增成功!"<<endl
}
Book*query(int bookid)//查找图书
{
for(int i=0i<=topi++)
if(book[i].getno()==bookid&&book[i].gettag()==0)
return NULL
}
void bookdata()//图书库维护
void disp()
{
for(int i=0i<=topi++)
if(book[i].gettag()==0)
book[i].disp()
}
~BDatabase()//析构函数,将book[]写入book.txt文件中
{
fstream file("book.txt",ios::out)
for (int i=0i<=topi++)
if(book[i].gettag()==0)
file.write((char*)&book[i],sizeof(book[i]))
file.close()
}
}
void BDatabase::bookdata()
{
int choice
char bname[40]
int bookid
Book *b
while(choice!=0)
{
cout<<"图书管理 1新增 2更该 3删除 4查找 5显示 6全删 0退出"<<endl
cin>>choice
switch(choice)
{
case 1:
cout<<"输入图书编号:"
cin>>bookid
cout<<"输入图书书名:"
cin>>bname
addbook(bookid,bname)
break
case 2:
cout<<"输入图书编号:"
cin>>bookid
b=query(bookid)
if(b==NULL)
{
cout<<"该图书不存在"<<endl
break
}
cout<<"输入新书名:"
cin>>bname
b->setname(bname)
cout<<"更名成功!"<<endl
break
case 3:
cout<<"输入图书编号:"
cin>>bookid
b=query(bookid)
if(b==NULL)
{
cout<<"该图书不存在!"<<endl
break
}
b->delbook()
break
case 4:
cout<<"请输入图书编号:"
cin>>bookid
b=query(bookid)
if(b==NULL)
{
cout<<"该书不存在!"<<endl
break
}
b->disp()
break
case 5:
disp()
break
case 6:
clear()
break
}
}
}
void main()
{
int choice=1,bookid,readerid
RDatabase ReaderDB
Reader *r
BDatabase BookDB
Book *b
while(choice!=0)
{
cout<<" 1借书 "<<endl
cout<<" 2还书 "<<endl
cout<<" 3图书维护 "<<endl
cout<<" 4读者维护 "<<endl
cout<<" 0离开 "<<endl
cin>>choice
switch(choice)
{
case 1:
cout<<"借书,请输入读者编号:"
cin>>readerid
cout<<"图书编号:"
cin>>bookid
r=ReaderDB.query(readerid)
if(r==NULL)
{
cout<<"哈哈,借书成功!"
break
}
b=BookDB.query(bookid)
if(b==NULL)
{
cout<<"不存在该书!"<<endl
break
}
if(b->borrowbook()==0)
{
cout<<"该书已借"<<endl
break
}
r->borrowbook(b->getno())
break
cout<<"借书成功!"<<endl
case 2:
cout<<"还书,请输入读者编号:"
cin>>readerid
cout<<"请输入图书编号;"
cin>>bookid
r=ReaderDB.query(readerid)
if(r==NULL)
{
cout<<"不存在该读者!"<<endl
break
}
b->retbook()
r->retbook(b->getno())
break
cout<<"还书成功!"<<endl
case 3:
BookDB.bookdata()
break
case 4:
ReaderDB.readerdata()
break
}
}
}
【输出结果】
1借书
2还书
3图书管理
4读者服务
0退出
3
图书管理 1新增 2更该 3删除 4查找 5显示 6全删 0退出
1
输入图书编号:1111
输入图书书名:武林外传
新增成功!
图书管理 1新增 2更该 3删除 4查找 5显示 6全删 0退出
1
输入图书编号:2222
输入图书书名:今夜无眠
新增成功!
图书管理 1新增 2更该 3删除 4查找 5显示 6全删 0退出
0
1借书
2还书
3图书管理
4读者服务
0退出
4
读者服务 1新增 2更该 3删除 4查找 5显示 6全删 0退出
1
请输入读者编号:001
读入读者姓名:周强
读者服务 1新增 2更该 3删除 4查找 5显示 6全删 0退出
0
1借书
2还书
3图书管理
4读者服务
0退出
1
借书,请输入读者编号:001
图书编号:1111
哈哈,借书成功! 1借书
2还书
3图书管理
4读者服务
0退出
2
还书,请输入读者编号:001
请输入图书编号;1111
还书成功!
1借书
2还书
3图书管理
4读者服务
0退出
3
图书管理 1新增 2更该 3删除 4查找 5显示 6全删 0退出
2
输入图书编号:2222
输入新书名:金庸全集
更名成功!
Press any key to continue
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)