图书管理系统
Posted 望北i
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图书管理系统相关的知识,希望对你有一定的参考价值。
问题描述
设计一个计算机管理系统完成图书管理基本业务。
每种书的登记内容包括书号、书名、著作者、现存量和库存量;
对书号建立索引表(线性表)以提高查找效率;
系统主要功能如下:
a) 采编入库:新购一种书,确定书号后,登记到图书帐目表中,如果表中已有,则只将库存量增加;
b) 借阅:如果一种书的现存量大于0,则借出一本,登记借阅者的书证号和归还期限,改变现存量;
c) 归还:注销对借阅者的登记,改变该书的现存量。
问题分析
利用函数式编程完成主要功能,对每种书的登记采用结构体储层,再用链表将其链接。,使用链表提高查询书的速度,对于借阅者的书证号和归还日期采用结构体数组储存。再借阅成功后,此书的现存量减一而库存量不变,再还书过后对结构体数组进行清除操作。
核心代码
储存书:该代码是对每一本书的储存,采用结构体的形式储存。
typedef struct BookShelf{ //每一本书的声明
char num[10]; //书号
char name[10]; //书名
char writer[10]; //书作者
int xiancun; //现存量
int kucun; //库存量
}Book;
借阅者的信息:该代码是将每一个借阅者信息存进一个结构体数组中去,当还书过后,将借阅者信息进行覆盖实现删除功能。
struct Browwer{ //借阅者信息
int peoplenumber; //书证号
int month; //月
int date; //日
}B[100];
链表的声明:链表分为数据域和指向下一个结点的指针
typedef struct Lnode{ //链表的声明
Book data;
struct Lnode *next;
}Lnode, *Linklist;
初始化链表:把头结点的next域指向空,如果已经为空的时候直接返回就可以
void EmptyList(Linklist L){ //初始化链表
if(L->next == NULL)
return;
else
L->next = NULL;
}
生成一个结点:生成一个结点函数,方便其他函数调用,malloc申请结点指针空间,这里因为是char类型的数组的原因所以用strcpy函数进行赋值,剩余两个数据使用int类型的,所以可以直接赋值,把书的信息存储到这个结点中,这个的next域指向空。返回此节点。
Lnode *CreateNode(Book book1){ //生成一个结点
Lnode *pnext = (Lnode *)malloc(sizeof(Lnode)); //malloc申请结点指针空间
strcpy(pnext->data.num, book1.num); //book1的数据赋值给结点
strcpy(pnext->data.name, book1.name);
strcpy(pnext->data.writer, book1.writer);
pnext->data.xiancun = book1.xiancun;
pnext->data.kucun = book1.kucun;
pnext->next = NULL;
return pnext;
}
图书入库:采用尾插法插入数据,定义一个结点指针,当指针指向空时创建结点调用生成结点函数CreateNode(),如果不为空,则访问next域判断是否为空,最后再将当前结点next结点相连接。
void InsertBook(Linklist L, Book book1){ //尾插法插入数据
Lnode *pnow = L; //结点指针
while((pnow->next != NULL)){ // 当链表指针指向空时
pnow = pnow->next;
}
Lnode *pnext = CreateNode(book1); //结点创建
pnow->next = pnext; //链接链表
}
借书过程:定义一个信号量和一个结点。用while循环中的if(!(strcmp(p->data.num,book1.num)))进行判断当书号相同时,书被借出去了,书的库存量应该减一,信号量置0,退出while循环,如果不同,则使指针结点访问下一个数据域,当数据域指向空时,提示用户书本信息错误,信号量置0,退出while循环。
void LendBook(Linklist L, Book book1){ //借书过程
int count = 1;
Lnode *p = L->next; //p是一个结点
while(count){
if(!(strcmp(p->data.num,book1.num))){ //比较书的书号
p->data.xiancun = p->data.xiancun - 1;
count = 0;
}
else if(p->next==NULL){
printf("书本信息错误\\n");
count = 0;
}
else
p=p->next;
}
}
显示图书信息:创建结点指针,用while循环控制,循环条件是结点指针不为空,在循环中输出书号,书名,著作者,现存量,库存量。结点指向下一个结点。
void Showbooks(Linklist L){ //显示图书信息
Lnode *p = L->next;
while(p != NULL){
printf("书本书号%s\\n", p->data.num);
printf("%s书本书名%s\\n", p->data.num, p->data.name);
printf("%s书本著作者%s\\n", p->data.num, p->data.writer);
printf("%s书本现存量%d\\n", p->data.num, p->data.xiancun);
printf("%s书本库存量%d\\n", p->data.num,p->data.kucun);
p = p->next;
}
}
还书过程:其过程与借书原理差不多,定义一个信号量和一个结点。用while循环中的if(!(strcmp(p->data.num,book1.num)))进行判断当书号相同时,书被借出去了,书的库存量应该加一,信号量置0,退出while循环,如果不同,则使指针结点访问下一个数据域,当数据域指向空时,提示用户书本信息错误,信号量置0,退出while循环。
void BackBook(Linklist L, Book book1, Browwer B[], int i){ //还书过程
int count = 1;
Lnode *p = L->next;
while(count){
if(!(strcmp(p->data.num,book1.num))){
p->data.xiancun = p->data.xiancun + 1;
count = 0;
DeletePeople(B, i);
}
else if(p->next==NULL){
printf("书本信息错误\\n");
count = 0;
}
else
p=p->next;
}
}
添加已有的图书:定义信号量,用while循环,创建头节点指针,当输入的书号与存储在结构体中的书号相同时,库存量加一,使信号量置为零,从而退出循环。
void AddBook(Linklist L, Book book1,int i){ //库存增加书过程
int count = 1;
Lnode *p = L->next;
while(count){
if(!(strcmp(p->data.num,book1.num))){
p->data.kucun = p->data.kucun + i;
count = 0;
}
}
}
借书信息:利用for循环访问储存借书的结构体数组并输出。
void ShowBorrow(Browwer B[], int a){ //借书信息
for(int i = 0; i < a; i++){
printf("借阅者书证号:%d\\n", B[i].peoplenumber);
printf("还书日期:%d月%d号\\n", B[i].month, B[i].date);
}
}
删除借阅人信息:再还书过后,将借阅人的信息覆盖为零。(这一部分我写的有很大问题,暂时没找到有效的方法解决)
void DeletePeople(Browwer B[], int b){ //删除借阅人信息
B[b].peoplenumber = 0;
B[b].month = 0;
B[b].date = 0;
}
退出:输入零直接退出
case '0' : {
printf("退出系统成功\\n");
count = 0;
}
Main代码:
int main(){
Linklist *head;
Lnode L;
EmptyList(&L);
char choice;
int count = 1;
int m;
int number;
while(count){
printf("+++++++++++++++图书管理系统+++++++++++\\n");
printf("+------------------------------------+\\n");
printf("+(请按相应的数字键选择您所需要的操作)+\\n");
printf("+------------------------------------+\\n");
printf("+ 1.图书入库 2.借阅 +\\n");
printf("+ 3.归还 4.借阅者信息 +\\n");
printf("+ 5.显示图书 0.退出 +\\n");
printf("+ 6.库存里增加图书\\n");
rewind(stdin);
scanf("%c", &choice);
switch(choice) {
case '1' : {
printf("你想输入多少种类书籍\\n");
scanf("%d", &number);
for(int i = 0; i < number; i++){
Book book1;
printf("请输入书号\\n");
rewind(stdin); //rewind(stdin)清除标准输入的按键缓冲区。rewind函数是把指定流的读写指针重新指向开头
scanf("%s", &book1.num);
printf("请输入书名\\n");
rewind(stdin);
scanf("%s", &book1.name);
printf("请输入著作者\\n");
rewind(stdin);
scanf("%s", &book1.writer);
printf("请输入现存量\\n");
rewind(stdin);
scanf("%d", &book1.xiancun);
book1.kucun = book1.xiancun;
InsertBook(&L, book1);
printf("第%d次录入完成\\n", i + 1);
}
break;
}
case '2' : {
Book book1;
int i = 1;
int k = 0;
do{
printf("请输入你的书证号\\n");
rewind(stdin);
scanf("%d", &B[k].peoplenumber);
printf("请输入你想借阅书的书号\\n");
rewind(stdin);
scanf("%s", &book1.num);
printf("请输入你的归还日期\\n");
rewind(stdin);
scanf("%d %d", &B[k].month, &B[k].date);
k++;
printf("是否继续添加,请输入1 or 0\\n");
rewind(stdin);
scanf("%d", &i);
LendBook(&L, book1);
m = k;
}while(i);
printf("借阅成功\\n");
break;
}
case '3' : {
Book book1;
int ShuZhengHao;
int i;
char SH[10];
printf("请输入你的书证号\\n");
scanf("%d", &ShuZhengHao);
printf("请输入你借阅书的书号\\n");
scanf("%s", &book1.num);
for(i = 0; i < m; i++){
if(ShuZhengHao == B[i].peoplenumber){
BackBook(&L, book1, B , i);
}
}
break;
}
case '4' :{
ShowBorrow(B,m);
printf("借书信息查询成功\\n");
break;
}
case '5':{
Showbooks(&L);
printf("图书信息查询成功\\n");
break;
}
case '6':{
Book book1;
int i;
printf("请输入书号\\n");
rewind(stdin); //rewind(stdin)清除标准输入的按键缓冲区。rewind函数是把指定流的读写指针重新指向开头
scanf("%s", &book1.num);
printf("请输入增加量\\n");
rewind(stdin);
scanf("%d", &i);
AddBook(&L,book1,i);
printf("添加成功\\n");
break;
}
case '0' : {
printf("退出系统成功\\n");
count = 0;
}
default :
printf("你输入的有误\\n");
break;
}
}
return 0;
}
rewind(stdin)函数作用参照此篇文章
源程序:
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<stdlib.h>
typedef struct BookShelf{ //每一本书的声明
char num[10]; //书号
char name[10]; //书名
char writer[10]; //书作者
int xiancun; //现存量
int kucun; //库存量
}Book;
typedef struct Lnode{ //链表的声明
Book data;
struct Lnode *next;
}Lnode, *Linklist;
struct Browwer{ //借阅者信息
int peoplenumber; //书证号
int month; //月
int date; //日
}B[100];
void EmptyList(Linklist L){ //初始化链表
if(L->next == NULL)
return;
else
L->next = NULL;
}
void DeletePeople(Browwer B[], int b){ //删除借阅人信息
B[b].peoplenumber = 0;
B[b].month = 0;
B[b].date = 0;
}
Lnode *CreateNode(Book book1){ //创建一个结点
Lnode *pnext = (Lnode *)malloc(sizeof(Lnode)); //malloc申请结点指针空间
strcpy(pnext->data.num, book1.num); //book1的数据赋值给结点
strcpy(pnext->data.name, book1.name);
strcpy(pnext->data.writer, book1.writer);
pnext->data.xiancun = book1.xiancun;
pnext->data.kucun = book1.kucun;
pnext->next = NULL;
return pnext;
}
void InsertBook(Linklist L, Book book1){ //尾插法插入数据
Lnode *pnow = L; //结点指针
while((pnow->next != NULL)){ // 当链表指针指向空时
pnow = pnow->next;
}
Lnode *pnext = CreateNode(book1); //结点创建
pnow->next = pnext; //链接链表
}
void LendBook(Linklist L, Book book1){ //借书过程
int count = 1;
Lnode *p = L->next; //p是一个结点
while(count){
if(!(strcmp(p->data.num,book1.num))){ //比较书的书号
p->data.xiancun = p->data.xiancun - 1;
count = 0;
}
else if(p->next==NULL){
printf("书本信息错误\\n");
count = 0;
}
else
p=p->next;
}
}
void BackBook(Linklist L, Book book1,以上是关于图书管理系统的主要内容,如果未能解决你的问题,请参考以下文章