本篇文章主要是介绍在 Linux 系统下采用 C 语言开发的图书管理系统,开发的系统能够实现增、删、改、查、借阅和浏览图书信息,采用动态函数来实现图书信息的存储。 具体的内容可查看本文章,欢迎广大朋友们前来学习和指教。如果有需要源代码的朋友们可点击博主的主页资源页面进行下载。
一、设计思路
本系统是利用 C 语言在操作系统环境下开发的图书管理系统,主要实现了图书信息管理的功能,通过此系统可以对图书馆库存图书信息进行管理和维护操作。实现了图书馆内管理的一般功能,包括查询、删除、统计、修改、图书信息等,所设计的系统以菜单方式工作,为用户提供清晰的使用提示,依据用户的选择来进行各种处理,并且在此过程中能够尽可能的兼容用户使用过程中可能出现的异常情况。图书信息包括编号、书名、作者、出版社、出版日期、价格等,图书信息的录入要求和显示要求是一定的规范要求,录入的图书信息用文件形式保存,并可以对其进行浏览、查询、修改、删除等基本操作。
二、开发环境
(1)操作系统:Windows 10 专业版(没有要求)
(2)虚拟机版本:Vmware Workstation Pro14
(3)Linux 版本:Centos 7
(4)编译器:gcc 编译器
三、系统流程图
(1)系统功能总体流程图
(2)借阅图书功能流程图
(3)归还图书功能流程图
四、数据库设计
1、数据存储结构
首先定义一个结构体变量,通过定义的结构体变量来保存图书的属性以及图书借出与归还的相关信息,也保证了后面各子函数的相互嵌套调用,并且降低了系统的开支。为了便于统计,将书的数量以及库存定义于同一个结构体中,定义的数据存储如下:
struct book
{
char number[m];//编号
char name[m];//书名
char writer[m];//作者
int count;//总数
int loan;//借出
int residue;//剩余
}book;
struct book bk[MAX]; //图书结构体
2.动态函数声明
系统调用动态函数 open、read、write 以及库函数 snprintf、sscanf 的格式声明如下:
int open(const char *pathname,int flags); //pathname为打开的文件名称,flag为标志信息
ssize_t read(int fd,void *buf,size_t count);//fd为文件描述符,buf为写入字符串,count为字符串大小
ssize_t write(int fd,const void *buf,size_t count);//fd为文件描述符,buf为写入字符串,count为字符串大小
int snprintf(char *restrict buf,size_t n,const char * restrict format....);
int sscanf(const char *str,const char *format.....);
通过 open 函数创建一个 txt 文本文件,然后将输入的有关图书的属性全部通过文件保存,输入图书的一个属性,通过 write 函数写入文件,对于整型数据,通过 snprintf 函数将其转变为字符串,并存入,读出则通过 sscanf 函数,将字符串转变为对应的数据。保存到文件中的数据在读取过程中,通过 read 来读取进入对应的结构体数组当中。
3.函数功能模块
(1)添加信息函数:调用add_book()函数,通过输入要录入的图书数量,再依次输入图书的属性,并且输入过程当中,通过write系统调用函数,边输入边存储数据进入文件,输入完成后,退出添加图书函数模块;
void add_book()//添加函数
{
int i;//变量i
int fd;//文件描述符
int number;//书的数量
fd=open("t.txt",O_RDWR|O_APPEND|O_CREAT);//打开文件t.txt,存在打开,不存在创建、可追加、读写数据进入文件
if(fd<0)//判断文件状态
{
perror("文件打开失败!\n");
exit(-1);
}
printf("请输入添加的图书数量:");
scanf("%d",&number);//输入书的数量
for(i=0;i<number;i++)//输入number个书的数量
{
printf("添加第%d本图书的信息:\n",i+1);
printf("编号:");
scanf("%s",bk[i].number);//输入编号
write(fd,bk[i].number,sizeof(bk[i].number));//编号写入文件
printf("书名:");
scanf("%s",bk[i].name);//输入姓名
write(fd,bk[i].name,sizeof(bk[i].name));//姓名写入文件
printf("作者:");
scanf("%s",bk[i].writer);//输入作者
write(fd,bk[i].writer,sizeof(bk[i].writer));//作者写入文件
printf("数量:");
scanf("%d",&bk[i].count);//输入总数
snprintf(str,m,"%d ",bk[i].count);//整型转化为字符串
write(fd,str,sizeof(str));//字符串存入文件
book_count=bk[i].count;
printf("借出(0):");
scanf("%d",&bk[i].loan);//初始化借出数
snprintf(str1,m,"%d ",bk[i].loan);//整型转化为字符串
write(fd,str1,sizeof(str1)); //字符串存入文件
printf("剩余(%d):",bk[i].count);
scanf("%d",&bk[i].residue);//初始化剩余数
snprintf(str2,m,"%d\n",bk[i].residue);//整型转化为字符串
write(fd,str2,sizeof(str2)); //字符串存入文件
}
book_number=number;//书总数赋值于全局变量
close(fd);//关闭文件
read_book();//读取文件
}
(2)查询信息函数:通过调用find_book()函数,根据你输入需要查询的图书信息,通过遍历文件中的数据,如果文件中存在该图书相关信息,则输出图书信息;反之,提示信息,图书不存在;
void find_book()//查询函数
{
int i;
int flag=0;//标记,不存在为0,存在为1
char name[m];//定义变量
printf("请输入查询的书名为:");
scanf("%s",name);//输入变量
for(i=0;i<book_number;i++)//遍历所有图书
{
if(strcmp(bk[i].name,name)==0)//找到
{
flag=1;//标记为1
//输出书的信息
printf("编号:%s\n",bk[i].number);
printf("书名:%s\n",bk[i].name);
printf("作者:%s\n",bk[i].writer);
printf("总数:%d\n",bk[i].count);
printf("借出:%d\n",bk[i].loan);
printf("剩余:%d\n",bk[i].residue);
}
}
if(flag==0)//未找到
{
printf("没有找到%s图书信息\n",name);
}
}
(3)借阅信息函数:通过调用borrow_book()函数,当文件读取进入结构体数组后,通过输入你需要借出的书名,遍历结构体数组,如果存在,则提示借阅该书籍的本数,如果借出数大于书籍总数,则默认借出数为书籍总数;如果不存在,则提示书籍不存在;
void borrow_book()//借出函数
{
int i,t;
int num;
int flag=0;
char name[m];
printf("请输入借阅的书名:");
scanf("%s",name);
for(i=0;i<book_number;i++)
{
if(strcmp(bk[i].name,name)==0)//比较图书
{
flag=1;
printf("已找到%s书籍,总数%d,已借出%d,剩余%d:\n",name,bk[i].count,bk[i].count-bk[i].residue,bk[i].residue);//提示相关书籍信息
printf("输入借阅%s的数量:",name);
scanf("%d",&num);//输入借出数量
if(num>bk[i].count)//借出数大于书总数
{
printf("最多可借出%d本书籍\n",bk[i].count);
num=bk[i].count; //借出数赋值于书总数
}
bk[i].residue=bk[i].count-num;//求剩余数
bk[i].loan=num;//借出数赋值
printf("%s成功借出\n",name);
}
}
if(flag==0)
{
printf("没有任何%s图书信息\n");
}
}
(4)归还信息函数:通过调用return_book()函数,输入你需要归还的书籍书名,如果书籍未借出,则无需归还,若书籍存在,则输入要归还的书的本数,最后提示归还成功;反之,归还失败;
void return_book()//归还函数
{
int i;
int flag=0;
int total=0;
int number=0;//定义归还书数量
char name[m];
printf("请输入归还的书名:");
scanf("%s",name);
for(i=0;i<book_number;i++)
{
if(strcmp(bk[i].name,name)==0)
{
flag=1;
printf("输入归还%s的数量:",name);
scanf("%d",&number);//输入归还书数量
total=bk[i].residue+number;//更新剩余数
if(bk[i].loan==0)//没有借出
{
printf("%s没有借出,无需归还\n");
break;
}
if(total<=bk[i].count)//有借出
{
bk[i].loan=bk[i].loan-number;//更新借出数
bk[i].residue=number+bk[i].residue;//更新剩余数
printf("%s归还成功\n",name);
break;
}
}
}
if(flag==0)
{
printf("没有任何%s图书信息\n");
}
}
(5)删除信息函数:调用delete_book()函数,输入需要删除的书籍书名,遍历所有图书信息,存在则删除该图书所有信息;不存在则提示信息错误;
void delete_book()//删除图书
{
int i,j;
int flag=0;//定义标记
char name[m];
printf("输入删除书籍的书名:");
scanf("%s",name);
for(i=0;i<book_number;i++)
{
if(strcmp(bk[i].name,name)==0)
{
flag=1;
if(i==book_number)//删除的书在最后一个
book_number-=1;//书总数减1
else//在中间
{
bk[i]=bk[book_number-1];
book_number-=1;
}
printf("成功删除%s书籍信息\n",name);
}
}
if(flag==0)
{
printf("没有任何%s图书信息\n");
}
}
(6)统计信息函数:调用statistic_book()函数,从文件中读取信息后,遍历所有图书,并且输出所有图书信息,当有书籍的输入、借阅以及归还时,更新图书状态信息,并且打印出所有图书相关信息;
void statistic_book()//统计函数
{
int i;
int flag=0;
printf("编号\t书名\t作者\t总数\t借出\t剩余\n");
for(i=0;i<book_number;i++)//遍历所有图书
{
flag=1;
printf("%s\t",bk[i].number);
printf("%s\t",bk[i].name);
printf("%s\t",bk[i].writer);
printf("%d\t",bk[i].count);
printf("%d\t",bk[i].loan);
printf("%d\n",bk[i].residue);
}
if(flag==0)
{
printf("没有任何图书信息\n");
}
}
(7)读取文件函数:调用read_book()函数,将add_book()函数中输入文件的所有数据进行读出,并且将读出的信息存储进入结构体数组中,便于对图书进行相关操作;
void read_book()//读取文件
{
int t;
int fd;//文件描述符
//定义总数、借出数、剩余数变量
int num;
int num1;
int num2;
book_number=0;
//定义编号、书名、作者变量
char number[m];
char name[m];
char writer[m];
fd=open("t.txt",O_RDONLY);//打开文件
if(fd<0)//打开失败
{
perror("文件打开失败!");
}
else
{
while((t=read(fd,number,sizeof(number)))!=0&&t!=-1)//读取文件中的数据
{
strcpy(bk[book_number].number,number);//文件中读取的数据付给结构体
read(fd,name,sizeof(name));//读取书名
strcpy(bk[book_number].name,name);//文件中读取的数据付给结构体
read(fd,writer,sizeof(writer));//读取作者
strcpy(bk[book_number].writer,writer);//文件中读取的数据付给结构体
read(fd,str,sizeof(str));//读取总数
sscanf(str,"%d",&num);//字符串转化为整数
bk[book_number].count=num;//赋值为结构体
read(fd,str1,sizeof(str1));
sscanf(str1,"%d",&num1);//字符串转化为整数
bk[book_number].loan=num1;//赋值为结构体
read(fd,str2,sizeof(str2));//读取借出数
sscanf(str2,"%d",&num2);//字符串转化为整数
bk[book_number].residue=num2;//赋值为结构体
book_number++;
}
}
close(fd);//关闭文件
}
五、功能运行结果
1.功能选择页面
2.添加图书信息
3.查询图书信息
4.借阅图书信息
5.归还图书信息
6.删除图书信息
7.统计图书信息
8.文件读取信息
9.退出管理系统