当前位置: 首页 > news >正文

基于C语言+SQL Server2008实现(控制台)图书管理系统

第1章 概述

1.1项目背景

随着科技的发展,尤其是计算机技术的迅猛发展,图书馆管理的问题从以往的人工管理,到现在的电脑化,系统化,是对图书馆管理方法的质的飞跃,这些技术不仅让图书馆管理变得更加方便、快捷、提高效率,对于用户来说也是有极大地帮助,系统化的图书馆让人们可以更方便的去找书,借书,还书等等一系列的功能,从而让图书馆实现了它的最大化价值。同时对于图书馆本身来说,通过系统,它可以提高图书管理的效率,也是图书馆的科学化、正规化管理的最好方法。所以,图书馆管理系统的研究开发,是一个特别值得去做的研究。

1.2编写目的

根据所学的数据库系统与程序设计的知识,针对图书管理系统,进行系统的需求分析,系统设计,数据库设计,编码,测试等,完成题目要求的功能,从而达到掌握开发一个小型数据库的目的。

1.3软件定义

本系统采用VC++6.0集成开发系统作为前台开发Windows窗体控制平台,采用SQLServer2008作为后台数据库的管理程序。

1.4开发环境

本系统适合运用于图书馆针对管理借阅者借阅图书。

下面简单介绍一下本系统的运行环境:

操作系统:Windows 7

数据库服务器:Microsoft SQL Server2008

编程工具:VC++6.0

绘图工具:Microsoft Visio 2010

第2章 需求分析

2.1问题陈述

2.1.1基本功能

图书管理系统,实现读者信息的借阅证号、姓名、年龄、职业等信息的管理;实现对图书信息的图书号、作者名、出版社、单价等信息点的管理,实现借阅信息的借阅证号、书号、时间等信息的管理,实现对逾期读者的管理

2.1.2数据库需要实现的功能

创建存储过程查询图书的数量;创建视图查询借阅逾期信息;创建触发器当增加、删除、修改读者信息或者图书信息时自动修改相应表的数据更新;建立数据库相关表之间的参照完整性约束。

2.1.3系统需要实现的功能

能实现以下主要功能

l 图书基本情况的录入、修改、删除等基本操作。

l 实现借书功能。

l 实现还书功能。

l 实现对所有购进图书的分类查询和分类统计。

l 能够按书名、作者等分类查询现有图书的数量。

l 对超期的情况能自动给出提示信息。

2.2业务处理流程

2.3数据流图

2.4数据字典

(1)图书管理员

简述:图书馆管理人员

组成:

Admin_idCHAR(7)
Admin_passwordCHAR(8)
Admin_nameNCHAR(5)

有关处理逻辑:系统管理权限的代表。

(2)读者

简述:图书馆借书看书的对象

组成:

Reader_idCHAR(7)
Reader_passwordCHAR(8)
Reader_nameNCHAR(5)
Reader_sexNCHAR(1)
Reader_ageTINYINT
Reader_CompanyNVARCHAR(20)
Reader_workNVARCHAR(20)

有关处理逻辑:图书馆读者权限的代表。

(3)图书信息表

简述:图书馆的书目

组成:

Book_idCHAR(6)
Book_nameNVARCHAR(20)
Book_writerNCHAR(5)
Book_publisherNVARCHAR(20)
Book_priceSMALLINT
Book_introductionNVARCHAR(100)
Book_typeNVARCHAR(20)

有关处理逻辑:图书馆其他实体对书目的操作。

(4)借阅信息表

简述:图书馆读者借书还书的记录

组成:

Reader_idCHAR(7)
Book_idCHAR(6)
Borrow_timeDATE

有关处理逻辑:图书馆的读者与图书之间的关系。

(5)图书馆采购员

简述:图书馆图书采购的工作人员

组成:

Shopper_idCHAR(7)
Shopper_nameNCHAR(5)
Shopper_sexNCHAR(1)
Shopper_ageTINYINT

有关处理逻辑:图书馆图书增添处理。

(6)图书采购信息表

简述:图书馆采购记录

组成:

Shopper_idCHAR(7)
Book_idCHAR(6)
Shop_timeDATE

有关处理逻辑:图书馆采购员与图书的关系。

(7)图书历史借阅表

简述:借书的历史的记录

组成:

Reader_idCHAR(7)
Book_idCHAR(6)
Borrow_timeDATE
Return_timeDATE

有关处理逻辑:图书馆的读者与图书之间的关系。

第3章 概念结构设计

3.1ER模型图

3.1.1实体ER图

3.1.2实体联系ER图

3.1.3完整ER模型图

第4章 逻辑结构设计

4.1关系模式

针对图书管理信息系统的需求,通过对借书流程的分析以及对ER图的分析,设计如下面的关系模式:

1)读者信息表,包括的数据项有:(借阅证号、密码、姓名、性别、年龄、所在单位、职业);

2)图书信息表,包括的数据项有:(书号、书名、作者、出版社、价格、内容简介、图书类型、库存);

3)借书信息表,包括的数据项有:(书号、借书时间、借阅证号);

4)还书信息表,包括的数据项有:(书号、还书时间、借阅证号);

5)管理员信息表,包括的数据项有:(管理员号、密码、姓名);

6)采购员信息表,包括的数据项有:(采购员号、姓名、性别、年龄);

7)采购信息表,包括的数据项有:(采购员号、书号、采购时间);

4.2规范化基本表

经过对初始关系模式的规范化处理,以下关系模式中不存在部分函数依赖和传递函数依赖,已经达到3NF。

1)读者信息表,包括的数据项有:(借阅证号、密码、姓名、性别、年龄、所在单位、职业);

2)图书信息表,包括的数据项有:(书号、书名、作者、出版社、价格、内容简介、图书类型);

3)借阅信息表,包括的数据项有:(书号、借阅证号、借书时间);

4)管理员信息表,包括的数据项有:(管理员号、密码、姓名);

5)采购员信息表,包括的数据项有:(采购员号、姓名、性别、年龄);

6)采购信息表,包括的数据项有:(采购员号、书号、采购时间);

7)借阅历史表,包括的数据项有:(书号、借阅证号、借书时间、还书时间);

模型中画双划线的是主码,并且借阅证号和书号是借阅关系的外码,采购员号和书号是采购关系的外码。书号、借阅证号、借书时间是借阅历史表的外码;

第5章 物理结构设计

5.1数据库结构

本系统数据库表的物理设计是通过SQL命令来创建数据库的,对表的数据项以及参照完整性约束进行了设计。如下是部分表创建命令:

go
use Library_342
--创建读者表
CREATE TABLE Reader (Reader_id    CHAR(7)  PRIMARY KEY,Reader_password  CHAR(8) NOT NULL,Reader_name  NCHAR(5) NOT NULL,Reader_sex   NCHAR(1) DEFAULT '男', Reader_age   TINYINT,Reader_Company   NVARCHAR(20),Reader_work  NVARCHAR(20))
--创建图书表
CREATE TABLE Book (Book_id      CHAR(6) 	  PRIMARY KEY,Book_name    NVARCHAR(20) NOT NULL,Book_writer  NCHAR(5),Book_publisher  NVARCHAR(20),Book_price   SMALLINT,Book_introduction    NVARCHAR(100),Book_type    NVARCHAR(20) NOT NULL,Book_num int not null,Book_allnum int not null)

5.2视图、索引、主关键字、权限

1)视图

---创建超期罚款信息视图
CREATE VIEW view_overdue(Reader_id,Reader_name,Book_name,Borrow_time,"超期","罚款")
AS
SELECT Reader.Reader_id,Reader.Reader_name,Book.Book_name,Borrow.Borrow_time,DATEDIFF(DAY,Borrow.Borrow_time,CONVERT (date,GETDATE(),112))-30 ,(DATEDIFF(DAY,Borrow.Borrow_time,CONVERT (date,GETDATE(),112))-30)*0.05 
FROM Reader,Book,Borrow
WHERE Borrow.Book_id=Book.Book_id ANDReader.Reader_id=Borrow.Reader_id ANDDATEDIFF(DAY,Borrow.Borrow_time,CONVERT (date,GETDATE(),112))>30 
--创建图书借阅数量视图
CREATE VIEW view_hotbook(Book_id,Book_name,"当前借阅数量","被借阅总次数")
AS
SELECT Book.Book_id,Book.Book_name,Book.Book_allnum-Book.Book_num,Book_allnum-Book.Book_num+COUNT(History.Book_id)
FROM Book,History
WHERE History.Book_id=Book.Book_id
GROUP BY Book.Book_id,Book_name,Book.Book_allnum-Book.Book_num

2)索引

--在图书表上创建关于“图书类型”列的一个升序非聚集索引;
CREATE INDEX BookType ON Book(Book_type);

3)主关键字

详见数据库关系图;

4)权限

CREATE LOGIN login2 with password='abcd1234', default_database=Library_342
CREATE USER user2 FOR LOGIN login2 with default_schema=dbo
GRANT INSERT,SELECT,UPDATE,DELETE
ON Borrow
TO user2

5.3数据库关系图

5.4对数据库的操作

1)插入、修改、删除

这些基本操作可通过在数据库中直接操作,也可以在编写的图书管理系统中进行部分操作;

2)触发器

--创建TR_Borrow_insert_8_Booknum_exits触发器,每次最多能借8本书,判断图书库存,判断是否已借该书,并对图书库存进行更新
CREATE TRIGGER TR_Borrow_insert_8_Booknum_exits
ON Borrow AFTER insert
AS
IF (SELECT COUNT(Borrow.Reader_id) FROM Borrow,inserted
WHERE Borrow.Reader_id=inserted.Reader_id)>8
BEGIN PRINT '最多只能借8本书! '	ROLLBACK
END
else IF (SELECT Book.Book_num FROM Book,inserted
WHERE Book.Book_id=inserted.Book_id)=0
BEGIN PRINT '该图书库存不足! '	ROLLBACK
END
else
BEGIN UPDATE BookSET Book_num=Book_num-1WHERE Book_id in (SELECT Book_idFROM inserted)PRINT '图书库存已更新! '
END--创建TR_Borrow_Delete_Booknum触发器,当删除借阅记录时,对图书库存进行更新并将借阅记录记录到借阅历史表中    
CREATE TRIGGER TR_Borrow_Delete_Booknum
ON Borrow AFTER delete
AS
BEGIN UPDATE BookSET Book_num=Book_num+1WHERE Book_id in (SELECT Book_idFROM deleted)PRINT '图书库存已更新! 'INSERT INTO History(Reader_id,Book_id,Borrow_time)SELECT deleted.Reader_id,deleted.Book_id,deleted.Borrow_timeFROM deleted
END--创建TR_History_insert_Return_time触发器,当还书时还书时间不能比借书时间早      
CREATE TRIGGER TR_History_insert_Return_time
ON History AFTER INSERT
AS
IF (SELECT DATEDIFF(DAY,inserted.Return_time,inserted.Borrow_time) 
FROM inserted,History
WHERE History.Book_id=inserted.Book_id AND History.Reader_id=inserted.Reader_id) >0
BEGIN PRINT '归还日期不能比借书日期早! '	ROLLBACK
END--创建TR_Reader_Delete_Borrow触发器,当删除读者时,将该读者的借阅信息删除      
CREATE TRIGGER TR_Reader_Delete_Borrow
ON Reader  INSTEAD OF  delete
AS
BEGIN DELETEFROM BorrowWHERE Borrow.Reader_id in(SELECT Reader_idFROM deleted)PRINT '该读者的借阅信息已删除! 'DELETEFROM HistoryWHERE History.Reader_id in(SELECT Reader_idFROM deleted)PRINT '该读者的借阅历史已删除! 'DELETEFROM ReaderWHERE Reader_id in(SELECT Reader_idFROM deleted)PRINT '该读者已删除! '
END--创建TR_Book_Delete_Borrow_History触发器,当删除图书时,将该图书的借阅信息删除      
CREATE TRIGGER TR_Book_Delete_Borrow_History
ON Book INSTEAD OF delete
AS
BEGIN DELETEFROM BorrowWHERE Borrow.Book_id in (SELECT Book_idFROM deleted)PRINT '该图书的借阅信息已删除! 'DELETEFROM HistoryWHERE History.Book_id in (SELECT Book_idFROM deleted)PRINT '该图书的被借阅历史已删除! '	 DELETEFROM BookWHERE Book_id in(SELECT Book_idFROM deleted)PRINT '该图书已删除! '	 
END

3)存储过程

--存储过程查询某类图书的数量
CREATE  PROCEDURE  Book_Type_num@Book_type NVARCHAR(20)='自然科学'
ASSELECT Book_type, COUNT(Book.Book_id) '该类型的图书数量(一样的书只算一本)'FROM BookWHERE Book.Book_type = @Book_type GROUP BY Book_type--存储过程在Reader中插入一行数据,其各列数据均通过输入参数获得
CREATE PROC p_InsertReader@Reader_id    CHAR(7)  ,@Reader_password  CHAR(8),@Reader_name  NCHAR(5) ,@Reader_sex   NCHAR(1) , @Reader_age   TINYINT,@Reader_Company   NVARCHAR(20),@Reader_work  NVARCHAR(20)
ASINSERT INTO Reader  
VALUES(@Reader_id,@Reader_password,@Reader_name,@Reader_sex,@Reader_age,@Reader_age,@Reader_work)

第6章 物理结构设计

6.1系统功能结构图

6.2功能描述

1)用户登录:选择登录系统的用户类型,进行不同的功能使用;

2)查看图书信息:查看数据库中各种图书的信息,进行其他操作;

3)修改个人信息:对数据库中的个人信息进行更新;

4)还书:借阅信息的更新;

5)借书:插入借阅信息;

6)查看借阅记录:输出个人的借阅情况;

7)读者管理:对读者进行增、删、改操作;

8)图书管理:对图书进行增、删、改操作;

9)查看当前逾期信息:查看数据库中当前用户逾期罚款信息;

第7章 代码设计和界面设计

7.1代码设计

1)数据库的连接:本系统是通过VC嵌入式SQL来进行数据库的连接的,主要代码如下:

int CONNECT()
{EXEC SQL CONNECT TO MS-20170511WSQV.Library_342 USER abc.abcd; if(sqlca->sqlcode==0)         {        printf("Connection to SQL Server established\n");  }else{ printf("ERROR: Connection to SQL Server failed\n");return 1;       }  
}int DISCONNECT()
{EXEC SQL DISCONNECT ALL;if(sqlca->sqlcode==0)         {        printf("DISConnection to SQL Server established\n");  }else{ printf("ERROR: DISConnection to SQL Server failed\n");return 1;       } return 1;
}

2)主函数main:系统程序的主函数设计,通过调用其他函数来实现管理图书系统;

int main()
{int select_num;int login_num;CONNECT();start_meun();while(1){scanf("%d",&select_num);switch(select_num){case 1:break;case 0://退出系统{system("cls");DISCONNECT();printf(" ------------------------------------------------------------\n");printf("       -=  感谢使用,再见! =-           \n");printf(" ------------------------------------------------------------\n");system("pause");exit(0);}default:printf("输入错误,请重新输入:");continue;}break;}while(1){login_meun();//登录界面函数login_num=login ();//登录处理switch(login_num){case 1:admin();break;case 2:reader();break;}}
}

3)头文件:包含头文件、全局变量定义以及函数声明:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char LReader_num[20];
/**********函数声明**********/
int CONNECT();
int DISCONNECT();
void start_meun();     //初始界面
void login_meun();    //登录界面函数
int login (void);      //用户登录函数
void admin_menu();   //管理员功能界面函数
void reader_meun();   //读者功能界面函数
void admin();        //管理员函数
void reader();        //读者函数
void admin_reader();  //管理读者函数
void admin_book();   //管理图书函数
void allborrow();     //查看借阅情况函数
void overdue();      //超期罚款函数
void adminreader_menu();
void adminbook_menu();
void addreader();    //增加读者函数
void deletereader();  //删除读者函数
void updatereader();  //修改读者函数
void addbook();     //增加图书函数
void deletebook();   //删除图书函数
void updatebook();   //修改图书函数
void borrowbook();   //借书函数
void returnbook();    //还书函数
void searchpersonborrow();//查看个人借阅函数
void updateme();       //修改个人信息函数
void allbook();         //查看所有图书函数
void allreader();        //查看所有读者函数

4)用户登录函数:本系统用户分为两类,一类是读者,一类是管理员,分别拥有不一样的功能权限;区分两者的方法是链接数据库查询登录用户是否在数据库中的读者表中或者管理员表中;代码如下:

for(;;)
{printf("管理员账号:");scanf("%s",&admin_num);printf("登陆密码:");scanf("%s",&admin_pass);EXEC SQL SELECT Admin_id,Admin_password INTO :admin_num,:admin_passFROM AdminWHERE Admin_id=:admin_num AND Admin_password=:admin_pass;if(sqlca->sqlcode!=0){  printf("发生了错误%d\n",SQLCODE);count+=1;printf("帐号密码错误,请重新输入\n");if(count>=3){system("cls");DISCONNECT();printf(" ------------------------------------------------------------\n");printf("         -=  感谢使用,再见! =-         \n");printf(" ------------------------------------------------------------\n");system("pause");exit(0);}continue;} printf("登录成功!\n");break;
}

读者用户登录同上;

5)读着管理:管理员对于读者的管理操作,包括增删改,增加读者代码如下:

void addreader()
{char YN;printf("输入读者的ID:");scanf("%s",&LReader_id);printf("输入读者的密码:");scanf("%s",&LReader_password);printf("输入读者的名字:");scanf("%s",&LReader_name);printf("输入读者的性别:");scanf("%s",&LReader_sex);printf("输入读者的年龄:");scanf("%d",&LReader_age);printf("输入读者的所在单位:");scanf("%s",&LReader_Company);printf("输入读者的职业:");scanf("%s",&LReader_work);EXEC SQL INSERT INTO Reader  VALUES(:LReader_id,:LReader_password,:LReader_name,:LReader_sex,:LReader_age,:LReader_Company,:LReader_work);if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/{printf("发生了错误%d\n",SQLCODE);return 1;   } else{printf("增加成功!");}printf("是否需要打印(Y/N):");do{scanf("%s",&YN);}while(YN != 'N' && YN != 'n' && YN != 'Y' && YN != 'y');if (YN == 'y' || YN == 'Y'){printf("\n%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n","Reader_id","Reader_password","LReader_name","Reader_sex","Reader_age","Reader_Company","Reader_work");printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10d\t%-10s\t%-10s\n",LReader_id,LReader_password,LReader_name,LReader_sex,LReader_age,LReader_Company,LReader_work);printf("打印完成!返回主菜单!\n");return 1;}printf("操作完成!返回主菜单!\n");
}

删除与修改函数与之类似;

6)输出所有读者:运用游标,链接数据库将表中所有信息打印出来;代码如下:

void allborrow()
{int  count=0;EXEC SQL DECLARE AX CURSOR FORSELECT Reader_id,Book_id,Borrow_timeFROM Borrow;EXEC SQL OPEN AX;for ( ; ; ){EXEC SQL FETCH AX INTO :LReader_id,:LBook_id,:LBorrow_time;if (sqlca->sqlcode!=0){break;}if(count++ == 0){printf("借阅情况<未还>:");printf("\n%-10s %-10s %-15s\n","Reader_id","Book_id","Borrow_time");}printf("%-10s %-10s %-15s\n",LReader_id,LBook_id,LBorrow_time);}EXEC SQL CLOSE AX;count=0;EXEC SQL DECLARE BX CURSOR FORSELECT Reader_id,Book_id,Borrow_time,Return_timeFROM History;EXEC SQL OPEN BX;for ( ; ; ){EXEC SQL FETCH BX INTO :LReader_id,:LBook_id,:LBorrow_time,:LReturn_time :LNull;if (sqlca->sqlcode!=0){printf("打印完成!返回主菜单!\n");break;}if(count++ == 0){printf("借阅历史<已还>:");printf("\n%-10s %-10s %-15s %-15s\n","Reader_id","Book_id","Borrow_time","Return_time");}printf("%-10s %-10s %-15s %-15s\n",LReader_id,LBook_id,LBorrow_time,LReturn_time);}EXEC SQL CLOSE BX;
}

7)图书管理:管理员对于图书的管理操作,包括增删改,删除图书代码如下:

void deletebook()
{char YN;printf("请输入你要删除的图书的ID:");scanf("%s",&LBook_id);EXEC SQL SELECT Book_id,Book_name,Book_writer,Book_publisher,Book_price,Book_introduction,Book_type,Book_num,Book_allnum INTO :LBook_id,:LBook_name,:LBook_writer:LNull,:LBook_publisher:LNull,:LBook_price:LNull,:LBook_introduction:LNull,:LBook_type,:LBook_num,:LBook_allnumFROM Book WHERE Book_id=:LBook_id;if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/{printf("发生了错误%d\n",SQLCODE);return 1;   } printf("\n%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n","Book_id","Book_name","Book_writer","Book_publisher","Book_price","Book_intro..","Book_type","Book_num","Book_allnum");printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10d\t%-10s\t%-10s\t%-10d\t%-10d\n",LBook_id,LBook_name,LBook_writer,LBook_publisher,LBook_price,LBook_introduction,LBook_type,LBook_num,LBook_allnum);printf("是否删除该图书(Y/N):");do{scanf("%s",&YN);}while(YN != 'N' && YN != 'n' && YN != 'Y' && YN != 'y');if (YN == 'y' || YN == 'Y'){EXEC SQL DELETEFROM BookWHERE Book_id=:LBook_id;if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/{printf("发生了错误%d\n",SQLCODE);return 1;   } else{printf("删除成功!返回主菜单!\n");	}}
}

其他操作类似;

8)借阅信息函数:查看当前借阅的信息,连接数据库,输出已还借阅信息和未还的借阅信息,代码如下:

void allborrow()
{int  count=0;EXEC SQL DECLARE AX CURSOR FORSELECT Reader_id,Book_id,Borrow_timeFROM Borrow;EXEC SQL OPEN AX;for ( ; ; ){EXEC SQL FETCH AX INTO :LReader_id,:LBook_id,:LBorrow_time;if (sqlca->sqlcode!=0){break;}if(count++ == 0){printf("借阅情况<未还>:");printf("\n%-10s %-10s %-15s\n","Reader_id","Book_id","Borrow_time");}printf("%-10s %-10s %-15s\n",LReader_id,LBook_id,LBorrow_time);}EXEC SQL CLOSE AX;count=0;EXEC SQL DECLARE BX CURSOR FORSELECT Reader_id,Book_id,Borrow_time,Return_timeFROM History;EXEC SQL OPEN BX;for ( ; ; ){EXEC SQL FETCH BX INTO :LReader_id,:LBook_id,:LBorrow_time,:LReturn_time :LNull;if (sqlca->sqlcode!=0){printf("打印完成!返回主菜单!\n");break;}if(count++ == 0){printf("借阅历史<已还>:");printf("\n%-10s %-10s %-15s %-15s\n","Reader_id","Book_id","Borrow_time","Return_time");}printf("%-10s %-10s %-15s %-15s\n",LReader_id,LBook_id,LBorrow_time,LReturn_time);}EXEC SQL CLOSE BX;
}

9)逾期信息函数:连接数据库查看视图,输出超期罚款信息,代码如下:

void overdue()
{int  count=0;EXEC SQL DECLARE QX CURSOR FORSELECT *FROM view_overdue;EXEC SQL OPEN QX;for ( ; ; ){EXEC SQL FETCH QX INTO:LReader_id,:LReader_name,:LBook_name,:LBorrow_time,:LOver_time,:LFine;if (sqlca->sqlcode!=0){printf("发生了错误%d\n",SQLCODE);printf("打印完成!返回主菜单!\n");break;}if(count++ == 0){printf("\n%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n","Reader_id","LReader_name","Book_id","Borrow_time","超期[天]","罚款[元]");}printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10d\t%-10f\n",LReader_id,LReader_name,LBook_name,LBorrow_time,LOver_time,LFine);}EXEC SQL CLOSE QX;
}

10)借书函数:读者对于图书的借阅操作,代码如下:

void borrowbook()
{	char YN;allbook();printf("请输入你要借阅的图书的ID:");scanf("%s",&LBook_id);EXEC SQL SELECT Book_id,Book_name,Book_writer,Book_publisher,Book_price,Book_introduction,Book_type,Book_num,Book_allnum             INTO :LBook_id,:LBook_name,:LBook_writer:LLNull,:LBook_publisher:LLNull,:LBook_price:LLNull,:LBook_introduction:LLNull,:LBook_type,:LBook_num,:LBook_allnumFROM Book WHERE Book_id=:LBook_id;if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/{printf("发生了错误%d\n",SQLCODE);return 1;   } printf("\n%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n","Book_id","Book_name","Book_writer","Book_publisher","Book_price","Book_intro...","Book_type","Book_num","Book_allnum");printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10d\t%-10s\t%-10s\t%-10d\t%-10d\n",LBook_id,LBook_name,LBook_writer,LBook_publisher,LBook_price,LBook_introduction,LBook_type,LBook_num,LBook_allnum);printf("是否借阅该图书(Y/N):");do{scanf("%s",&YN);}while(YN != 'N' && YN != 'n' && YN != 'Y' && YN != 'y');if (YN == 'y' || YN == 'Y'){printf("输入借阅时间(2017-XX-XX):");scanf("%s",&LBorrow_time);EXEC SQL INSERT INTO Borrow(Reader_id,Book_id,Borrow_time)VALUES(:LReader_num,:LBook_id,:LBorrow_time);if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/{printf("发生了错误%d\n",SQLCODE);return 1;   }printf("借阅成功!打印借阅信息!\n");EXEC SQL SELECT Reader_id,Book_id,Borrow_time INTO :LReader_id,:LBook_id,:LBorrow_timeFROM BorrowWHERE Reader_id=:LReader_num AND Book_id=:LBook_id;if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/{printf("发生了错误%d\n",SQLCODE);return 1;   }printf("\n%-10s %-10s %-15s\n","Reader_id","Book_id","Borrow_time");printf("%-10s %-10s %-15s\n",LReader_id,LBook_id,LBorrow_time);printf("操作完成!返回主菜单!\n");}
}

11)还书函数:读者对于图书的借阅操作,代码如下:

void returnbook()
{char YN;printf("请输入你要归还的图书的ID:");scanf("%s",&LBook_id);EXEC SQL SELECT Reader_id,Book_id,Borrow_time INTO :LReader_id,:LBook_id,:LBorrow_timeFROM BorrowWHERE Reader_id=:LReader_num AND Book_id=:LBook_id;if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/{printf("发生了错误%d\n",SQLCODE);return 1;   }printf("\n%-10s %-10s %-15s\n","Reader_id","Book_id","Borrow_time");printf("%-10s %-10s %-15s\n",LReader_id,LBook_id,LBorrow_time);printf("是否归还该图书(Y/N):");do{scanf("%s",&YN);}while(YN != 'N' && YN != 'n' && YN != 'Y' && YN != 'y');if (YN == 'y' || YN == 'Y'){printf("输入归还时间(2017-XX-XX):");scanf("%s",&LReturn_time);EXEC SQL DELETE FROM BorrowWHERE Reader_id=:LReader_num AND Book_id=:LBook_id;if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/{printf("发生了错误%d\n",SQLCODE);return 1;   }EXEC SQL UPDATE HistorySET Return_time=:LReturn_timeWHERE Reader_id=:LReader_num AND Book_id=:LBook_id AND Borrow_time=:LBorrow_time;if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/{printf("发生了错误%d\n",SQLCODE);return 1;   }printf("归还成功!打印信息!\n");EXEC SQL SELECT Reader_id,Book_id,Borrow_time,Return_time INTO :LReader_id,:LBook_id,:LBorrow_time,:LReturn_time:LLNullFROM HistoryWHERE Reader_id=:LReader_num AND Book_id=:LBook_id AND Borrow_time=:LBorrow_time;if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/{printf("发生了错误%d\n",SQLCODE);return 1;   }printf("\n%-10s %-10s %-15s %-15s\n","Reader_id","Book_id","Borrow_time","Return_time");printf("%-10s %-10s %-15s %-15s\n",LReader_id,LBook_id,LBorrow_time,LReturn_time);printf("操作完成!返回主菜单!\n");}
}

12)个人信息修改函数:读者对于自己的个人信息修改操作;代码如下:

void updateme()
{char YN;printf("你的个人信息:\n");EXEC SQL SELECT Reader_id,Reader_password,Reader_name,Reader_sex,Reader_age,Reader_Company,Reader_work INTO:LReader_id,:LReader_password,:LReader_name,:LReader_sex:LNull,:LReader_age:LNull,:LReader_Company:LNull,:LReader_work:LNullFROM Reader WHERE Reader_id=:LReader_num;if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/{printf("发生了错误%d\n",SQLCODE);return 1;   } printf("\n%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n","Reader_id","Reader_password","LReader_name","Reader_sex","Reader_age","Reader_Company","Reader_work");printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10d\t%-10s\t%-10s\n",LReader_id,LReader_password,LReader_name,LReader_sex,LReader_age,LReader_Company,LReader_work);printf("是否修改(Y/N):");do{scanf("%s",&YN);}while(YN != 'N' && YN != 'n' && YN != 'Y' && YN != 'y');if (YN == 'y' || YN == 'Y'){printf("输入新的密码:");scanf("%s",&LReader_password);printf("输入新的名字:");scanf("%s",&LReader_name);printf("输入新的性别:");scanf("%s",&LReader_sex);printf("输入新的年龄:");scanf("%d",&LReader_age);printf("输入新的所在单位:");scanf("%s",&LReader_Company);printf("输入新的职业:");scanf("%s",&LReader_work);EXEC SQL UPDATE ReaderSET Reader_password=:LReader_password,Reader_name=:LReader_name,Reader_sex=:LReader_sex,Reader_age=:LReader_age,Reader_Company=:LReader_Company,Reader_work=:LReader_workWHERE Reader_id=:LReader_num;if(sqlca->sqlcode!=0) /*sqlcode!=0,表示操作不成功*/{printf("发生了错误%d\n",SQLCODE);return 1;   } else{printf("修改成功!查看修改结果!\n");EXEC SQL SELECT Reader_id,Reader_password,Reader_name,Reader_sex,Reader_age,Reader_Company,Reader_work INTO :LReader_id,:LReader_password,:LReader_name,:LReader_sex:LNull,:LReader_age:LNull,:LReader_Company:LNull,:LReader_work:LNullFROM Reader WHERE Reader_id=:LReader_id;		printf("\n%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n","Reader_id","Reader_password","LReader_name","Reader_sex","Reader_age","Reader_Company","Reader_work");		printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10d\t%-10s\t%-10s\n",LReader_id,LReader_password,LReader_name,LReader_sex,LReader_age,LReader_Company,LReader_work);	}printf("操作完成!返回主菜单!\n");return 1;}printf("操作完成!返回主菜单!\n");	
}

主要功能代码如上,部分功能代码类似不依次举例,详见附录或者工程代码文件;

7.2界面设计

1)初始界面

2)登录界面

3)管理员功能界面

4)读者功能界面

5)图书管理界面

6)读者管理界面

相关文章:

基于C语言+SQL Server2008实现(控制台)图书管理系统

第1章 概述 1.1项目背景 随着科技的发展&#xff0c;尤其是计算机技术的迅猛发展&#xff0c;图书馆管理的问题从以往的人工管理&#xff0c;到现在的电脑化&#xff0c;系统化&#xff0c;是对图书馆管理方法的质的飞跃&#xff0c;这些技术不仅让图书馆管理变得更加方便、快…...

Msf之Python分离免杀

Msf之Python分离免杀 ——XyLin. 成果展示&#xff1a; VT查杀率:8/73 (virustotal.com) 火绒和360可以过掉&#xff0c;但Windows Defender点开就寄掉了 提示&#xff1a;我用360测的时候&#xff0c;免杀过了&#xff0c;但360同时也申报了&#xff0c;估计要不了多久就寄…...

electron-updater实现electron全量版本更新

在 Electron 应用中使用 electron-updater 来实现自动更新功能时&#xff0c;通常你会在一个专门的模块或文件中管理更新逻辑。如果你想要使用 ES6 的 import 语法来引入 electron-updater&#xff0c;你需要确保你的项目已经配置好了支持 ES6 模块的构建工具&#xff08;如 We…...

Mysql梳理6——order by排序

目录 6 order by排序 6.1 排序数据 6.2 单列排序 6.3 多行排列 6 order by排序 6.1 排序数据 使用ORDER BY字句排序 ASC&#xff08;ascend&#xff09;:升序DESC(descend):降序 ORDER BY子句在SELECT语句的结尾 6.2 单列排序 如果没有使用排序操作&#xff0c;默认…...

Java设计模式—面向对象设计原则(三) -----> 依赖倒转原则DIP(完整详解,附有代码+案例)

文章目录 3.3 依赖倒转原则(DIP)3.3.1概述3.3.2 案例 3.3 依赖倒转原则(DIP) 依赖倒转原则&#xff1a;Dependency Inversion Principle&#xff0c;DIP 3.3.1概述 高层模块不应该依赖低层模块&#xff0c;两者都应该依赖其抽象&#xff1b;抽象不应该依赖细节&#xff0c;细…...

Linux操作系统 进程(3)

接上文 Linux进程优先级之后&#xff0c;我们了解到僵尸进程与孤儿进程的形成原因&#xff0c;既然是因为父进程没有接收子进程的退出状态导致的&#xff0c;那么我们该如何去获取子进程的退出状态呢&#xff1f;那本篇文章将围绕这个问题来解释进程。 环境 &#xff1a; vsco…...

QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第五期]

QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第五期] 第五期介绍&#xff1a;频道模块之接口授权管理和发言管理 目录 QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第五期]第五期介绍&#xff1a;频道模块之接口授权管理和发言管理获取机器人在频道可用权限列表…...

代码签名证书快速申请指南

申请代码签名证书是确保软件或应用程序在分发和安装过程中不被篡改的重要步骤。以下是详细的快速申请指南&#xff1a; 一、选择证书品牌和服务商 选择知名证书品牌&#xff1a;首先&#xff0c;选择一个国际知名的代码签名证书品牌&#xff0c;如GlobalSign、Digicert、Comod…...

安卓 uniapp跨端开发

HBuilder X 4.24 本地插件方式使用原生插件 例如 MT-TTS 地址PS: 播放 speek({text: ‘test’}) 应为 播放 speak({text: ‘test’})MT-TTS下载下来之后,将 nativeplugins 文件夹拷贝到 uniapp 项目根目录中manifest.json ---- App原生插件配置 运行 语音引擎测试文字转语音播…...

【高阶用法】uniapp的i18n多语言模块修复与增强(Typescript)

痛点 在i18n多语言模块使用过程中&#xff0c;发现下面几个问题&#xff0c;需要解决 1&#xff09;uni-best框架下&#xff0c;$t功能函数无法实时的切换语言&#xff0c;可能跟使用有关 2&#xff09;uni-best建议的translate方式在vue块外使用太繁琐&#xff0c;希望不用…...

SQL Server Data Tools (SSDT)入门教程

SSDT (SQL Server Data Tools) 是微软提供的一款用于开发、设计和管理SQL Server数据库的工具。它集成在Visual Studio中&#xff0c;允许开发人员和数据库管理员在统一的环境中进行数据库开发与管理。以下是关于SSDT的详细介绍&#xff1a; 1. 什么是SSDT&#xff1f; SQL S…...

窗户检测系统源码分享

窗户检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …...

2.计算机网络基础

2. 计算机网络基础 (1) 计算机网络的定义 计算机网络是指将地理位置不同、具有独立功能的多个计算机系统通过通信线路和设备连接起来,以功能完善的网络软件实现网络中资源共享的系统。最简单的定义是:计算机网络是一些互相连接的、自治的计算机系统的集合。最庞大的计算机网…...

硬中断,软中断恢复位置

汇编初始化栈指针&#xff0c;interrupt,svc preserve8 ;preserve8 和 restore8 通常用于保护寄存器的状态;以确保在函数调用前后某些寄存器的值保持不变area reset,code,readonlycode32entryb startldr pc,do_undefined;这些地址不能随便写&#xff0c;0x0,0x4,0x8....这些…...

MySQL基础(13)- MySQL数据类型

目录 一、数据类型概述 1.MySQL中的数据类型 二、整型 1.数据类型可选属性 2.使用建议 三、浮点数、定点数、位类型 1.类型介绍 2.浮点类型 3.定点数类型 4.位类型 四、日期时间类型 1.YEAR 2.DATE 3.TIME 4.DATETIME 5.TIMESTAMP 6.TIMESTAMP和DATETIME的区别…...

数据结构------二叉树简单介绍及实现

如果不是满二叉树或者完全二叉树&#xff0c;就要用链式存储 //搜索二叉树&#xff1a;左子树的所有值比根小&#xff0c;右子树的所有值比根大 // 实现查找&#xff0c;最多找高度次&#xff08;类似二分法&#xff09; //二分查找存在的问题&#xff1a…...

由一个 SwiftData “诡异”运行时崩溃而引发的钩深索隐(六)

概述 在 WWDC 24 中,苹果推出了数据库框架 SwiftData 2.0 版本。听说里面新增了能让数据记录“借尸还魂”的绝妙法器,到底是真是假呢? 我们在上篇博文中介绍了 History Trace 是如何稳妥的处理数据删除操作的。而在这里,我们将继续介绍 SwiftData 2.0 中另一个新特性:“墓…...

尚品汇-秒杀下单实现-页面轮询查询订单状态(五十三)

目录&#xff1a; &#xff08;1&#xff09;整合秒杀业务 &#xff08;2&#xff09;秒杀下单 &#xff08;3&#xff09;秒杀下单监听 &#xff08;4&#xff09;页面轮询接口 &#xff08;1&#xff09;整合秒杀业务 秒杀的主要目的就是获取一个下单资格&#xff0c;拥…...

2024年微电子与纳米技术国际研讨会(ICMN 2024) Microelectronics and Nanotechnology

文章目录 一、会议详情二、重要信息三、大会介绍四、出席嘉宾五、征稿主题六、咨询 一、会议详情 二、重要信息 大会官网&#xff1a;https://ais.cn/u/vEbMBz提交检索&#xff1a;EI Compendex、IEEE Xplore、Scopus大会时间&#xff1a;2024年9月20-22日地点&#xff1a;成都…...

2024最新版,人大赵鑫老师《大语言模型》新书pdf分享

本书主要面向希望系统学习大语言模型技术的读者&#xff0c;将重点突出核心概念与 算法&#xff0c;并且配以示例与代码&#xff08;伪代码&#xff09;帮助读者理解特定算法的实现逻辑。由于大语言模型技术的快速更迭&#xff0c;本书无法覆盖所有相关内容&#xff0c;旨在梳理…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...