引言:这个系统是我大一下册编写的,也没有再修改,C语言只学到简单的指针为止,对C的认识非常肤浅,并且没有代码经验,可以说这是我第一个能算上能实现功能的系统,仅仅借助书籍:程序设计第四版(谭浩强)、数据结构(清华大学出版社 C语言版),因此对于只要学过C语言的同学都应该能看明白,希望大家勿喷。注:程序配大量注释
- 主要知识点:结构体、单链表、循环、break、continue、strcmp(字符串比较)、fopen fwrite fclose(数据存储)等。
- 系统缺点:代码特别冗杂,有很多具有相似功能的没有整合;函数与函数之间只有单纯的地址传递;简单算法也是嵌套了太多循环,并没有从本质上优化算法。
- 系统优点(功能):拥有简单的交互界面;实现了系统的借书、还书、查找书籍、增添、删除、修改书籍的具体功能;并对每次启动系统进行数据录入和数据存储(前提:按系统正常退出);并对各项功能的误操作进行简单的报错提示;
- 如图:
- 代码
/*
作品:图书管理系统
出品人:小汪
时间:2018/6/1
*/
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include<stdlib.h>
struct book //书籍信息
{
int num; //编号
char name[20]; //书名称
char location[50]; //存放位置
};
struct book_date //存放书籍的方式(链表)
{
struct book date;
struct book_date *next;
};
/*顺序表建立
*/
int manage_menu(); //管理员菜单
struct book_date * linklist_book(); //创建链表
void putin_book(struct book_date *); //增加书籍
void change_book_information(struct book_date *); //修改或删除图书信息
void all_book(struct book_date *);// 显示所有图书基本信息
int Return_operation();
void borrow_book(struct book_date *); //借书
void return_book(struct book_date *); //还书
void get_only_oneworld(); //规定输入选项符号
int Main_menu();//主菜单
void put_date(struct book_date *); //预览图书
struct book_date * L;//指向头节点
void save_information(struct book_date *L); //录入数据 声明
void read_information(struct book_date *L); // 读取数据 声明
/*主函数
*/
int main()
{
L = linklist_book();
read_information(L);
Main_menu();
save_information(L);
return 0;
}
/*定输入选项符号
*/
void get_only_oneworld()
{
while (getchar() != '\n')
{
continue;
}
}
/* 链表初始化
*/
struct book_date *linklist_book()
{
struct book_date *head, *p;
p = (struct book_date *)malloc(sizeof(struct book_date));
if (p != NULL) //头节点分配成功
{
head = p;
p->next = NULL;
}
return head;
}
/*图书入库
*/
void putin_book(struct book_date *L)
{
system("cls");
int number = 0;//本次录入的数量
struct book_date *last, *now;
last = L;
while (last->next != NULL) last = last->next;//迭代到最后,可利于多次分批录入
printf("* * * * * * * * 图书正在入库中 * * * * * * * *\n");
printf("\n");
printf("# # # 结束本次录入请输入0 # # # \n");
printf("\n");
while (1)
{
now = (struct book_date *)malloc(sizeof(struct book_date));
printf("请输入书籍名称: ");
scanf("%s", now->date.name);
getchar();
if (strcmp(now->date.name, "0") == 0)
{
free(now);
break;
}
printf("请输入书籍编号: ");
scanf("%d", &now->date.num);
getchar();
if (now->date.num == 0)
{
free(now);
break;
}
printf("请输入取书的所在位置: ");
scanf("%s", now->date.location);
getchar();
if (strcmp(now->date.location, "0") == 0)
{
free(now);
break;
}
printf("\n");
last->next = now;
last = now;
++number;//本次录入的数量
}
last->next = NULL;
printf("\n");
printf("* * * * * * * * * * * * * * * * * * *\n");
printf("* *\n");
printf("* 图 书 馆 新 增 书 籍 %d\n", number);
printf("* *\n");
printf("* * * * * * * * * * * * * * * * * * *\n");
printf("\n");
printf("* * * * * * * * 录入完成!* * * * * * * * \n");
Return_operation();
}
/*修改或删除图书信息
*/
void change_book_information(struct book_date *L)
{
system("cls");
char celect[10];
int num; //修改书籍的编号
char b[20];
char flag[20]; // 继续修改(确认1,否则0)
struct book_date *p, *previous; //previous为要被修改数据的前一个节点
int fail = 3;
int ok = 0; // 判断循环是否跳出
p = L;
printf("* * * * * * * * 确认图书信息进行下列操作 * * * * * * * *\n");
do
{
p = L;
do
{
printf("请 输 入 查 询 图 书 的 编 号:");
scanf("%d", &num);
getchar();
while (p->next != NULL) //找到编号相同的节点
{
previous = p;
p = p->next;
if (p->date.num == num)
{
ok = 1;
break;
}
}
if (ok == 0) //没有找到就重新输入
{
printf("未 找 到 此 类 图 书!!! \n");
printf(" (剩余%d次)", --fail);
p = L;
}
else
{
printf("图 书 原 信 息 :\n");
printf("编号:%d \t《%s》\t 位置:%s\n", p->date.num, p->date.name, p->date.location);
printf("输入1:修改信息\n");
printf("输入2:删除书籍\n");
printf("输入任意字符:退出操作");
printf("\t ##请输入:");
scanf("%s", celect);
getchar();
if (strcmp(celect, "1") == 0)
{
printf("# 请 重 新 输 入 书 籍 相 关 信 息 (系统自动覆盖旧信息) #\n");
printf("编 号 :");
scanf("%d", &num);
getchar();
p->date.num = num;
printf("书 名 :");
scanf("%s", b);
getchar();
strcpy(p->date.name, b);
printf("存 放 位 置 :");
scanf("%s", b);
getchar();
strcpy(p->date.location, b);
break;
}
if (strcmp(celect, "2") == 0)
{
previous->next = p->next;
free(p);
break;
}
if (strcmp(celect, "1") != 0 || strcmp(celect, "2") != 0)
{
break;
}
}
} while (fail != 0);
if (fail == 0)
{
break;
}
else
{
printf("* * * * * * * * * * * * 修改完成 * * * * * * * * * * * *\n");
printf("继续输入1,否则任意字符:");
scanf("%s", flag);
getchar();
printf("\n");
}
} while (strcmp(flag, "1") == 0);
if (fail == 0)
{
printf("请 尽 快 联 系 相 关 负 责 人 ! ! !\n");
printf("! ! ! ! ! ! ! ! 修改失败 ! ! ! ! ! ! ! ! \n");
}
Return_operation();
}
/*借书
*/
void borrow_book(struct book_date *L)
{
system("cls");
char phone[20];
int number;
char garden[20];
char name[20];
int i; // 记录错误次数
struct book_date *p;
printf("* * * * * * * * 正在进行借书操作 * * * * * * * *\n");
printf("欢 迎 来 到 小 汪 书 店!!!\n");
if (L->next == NULL)
printf("暂 无 书 可 借 阅 ,请 等 待 管 理 员 录 入 书 籍\n");
else
{
printf("请 输 入 你 想 借 阅 书 籍 的 编 号:");
scanf("%d", &number);
getchar();
i = 3;
do //有3次重新输入机会
{
p = L->next; //p指向头节点
while (p != NULL) //循环到最后一个节点
{
if (number == p->date.num) //如果当前节点相等,就跳出循环
break;
else
p = p->next;
}
if (p == NULL) //判断结束条件,是跳出循环还是正常走出循环
{
printf("输 入 错 误 !未 录 入 此 编 号!\n");
printf("请 重 新 输 入 编 号(剩余操作次数%d):", i--);
scanf("%d", &number);
getchar();
}
else
{
strcpy(p->date.location, "已借出"); //借出书过后,借书位置显示为:在其他读者手中
break;
}
} while (i != 0); //有5次输入正确编码的机会
if (i == 0)
{
printf("! ! ! ! ! ! ! ! 为保证其他读者正常借阅,请尽快联系管理员 ! ! ! ! ! ! ! ! \n");
}
else
{
printf("* * * * * * * * 请输入你本人的基本信息 * * * * * * * *\n");
printf("\n");
printf(" 请 输 入 姓 名 :");
scanf("%s", name);
getchar();
printf(" 请 输 入 预 留 电 话 号 码:");
scanf("%s", phone);
getchar();
printf(" 请 输 人 你 所 在 年 级:");
scanf("%s", garden);
getchar();
printf("\n 系 统 正 在 为 您 办 理 借 书 手 续 请 稍 后 ......\n");
printf("* * * * * * * * * * * 借书成功 * * * * * * * * * * * *\n");
}
}
Return_operation();
}
//还书
void return_book(struct book_date *L)
{
system("cls");
struct book_date *p, *p1; //p是查询编号书籍信息地址,p1是查询是否有与输入位置相同的书籍地址
int number;
int i = 3; //错误输入编号的次数
p = L->next;
if (p==NULL)
{
printf("最 近 未 借 出 图 书 , 若 有 疑 问 请 联 系 管 理 员!!!!!\n 联 系 方 式:xxxxxxxx\n");
}
else
{
printf("亲 爱 的 读 者!\n");
printf("请 输 入 你 所 要 归 还 书 籍 的 编 号 :");
scanf("%d", &number);
do
{
while (p!= NULL) //查找与编号相对应的书籍资料
{
if (p->date.num == number && strcmp(p->date.location, "已借出") == 0) //找到了书籍
{
break;
}
p = p->next;
}
if (p == NULL)
{
i--;
printf("\n\n");
printf("输 入 不 正 确 !未 录 入 此 编 号!\n");
printf("请 重 新 输 入 书 籍 编 号 (剩余操作次数%d):", i);
scanf("%d", &number);
getchar();
p = L->next;
}
else
{
printf("\n编号:%d 书名:《%s》\t", p->date.num, p->date.name);
printf("输入新位置:");
scanf("%s", p->date.location);
getchar();
break;
}
} while (i != 0);
if (i != 0)
{
printf("* * * * * * * * 归还成功 * * * * * * * *\n");
}
else
{
printf("! ! ! ! ! ! ! ! 为保证其他读者正常借阅,请尽快联系管理员 ! ! ! ! ! ! ! ! \n");
}
}
Return_operation();
}
//读取数据
void read_information(struct book_date *L)
{
char c;
FILE *f1;
struct book_date *p, *p1;
if ((f1 = fopen("test1", "rb")) != NULL)
{
p = L;
while (1)
{
p1 = (struct book_date *)malloc(sizeof(struct book_date));
fread(p1, sizeof(struct book), 1, f1);
if (feof(f1))
{
free(p1);
break;
}
p->next = p1;
p = p1;
}
p->next = NULL;
fclose(f1);
}
}
//录入数据
void save_information(struct book_date *L)
{
struct book_date *p;
FILE *fp;
if ((fp = fopen("test1", "wb")) != NULL)
{
p = L;
while (p->next != NULL)
{
p = p->next;
fwrite(&p->date, sizeof(struct book), 1, fp);
}
fclose(fp);
}
}
/*现存书籍
*/
void now_book(struct book_date *L)
{
int n = 0;
struct book_date *p;
p = L;
while (p->next != NULL)
{
p = p->next;
if (strcmp(p->date.location, "已借出") != 0)
{
printf("编号:%d \t《%s》\t 位置:%s\n", p->date.num, p->date.name, p->date.location);
n++;
}
}
printf("\n");
printf("**************************\n");
printf("* *\n");
printf("* 现 存 书 籍 共 %d 册 * \n", n);
printf("* *\n");
printf("**************************\n");
printf("\n");
}
/*统计书籍数量
*/
void Statistical_books(struct book_date *L)
{
int n = 0; //总书籍数量
struct book_date *p;
p = L;
while (p->next != NULL)
{
p = p->next;
n++; //存在一个节点n+1
}
printf("* * * * * * * * * * * * * * * * * * *\n");
printf("* *\n");
printf("* 本 图 书 馆 图 书 现 共 计 %d 册 *\n", n);
printf("* *\n");
printf("* * * * * * * * * * * * * * * * * * *\n\n");
}
/*借出书籍统计
*/
void lend_book(struct book_date *L)
{
int n = 0; //借出书籍数量
struct book_date *p;
p = L;
while (p->next != NULL)
{
p = p->next;
if (strcmp(p->date.location, "已借出") == 0)
{
printf("编号:%d \t《%s》\t 位置:%s\n", p->date.num, p->date.name, p->date.location);
n++;
}
}
printf("\n");
printf("**************************\n");
printf("* *\n");
printf("* 已 借 出 书 籍 共 %d 册*\n", n);
printf("* *\n");
printf("**************************\n");
printf("\n");
}
/**/
/*预览图书
*/
void put_date(struct book_date *L)
{
struct book_date *p;
int number;
char server;
p = L->next;
if (p == NULL) //如果还未录入书籍时查询结果
{
printf("本 书 店 还 未 录 入 书 籍 , 请 等 待 管 理 员 录 入 书 籍\n");
}
else
{
printf("* * * * * * * * 查找书籍 * * * * * * * *\n");
printf("亲 爱 的 读 者 请 输 入 你 想 预 览 书 籍 的 编 号:");
scanf("%d", &number);
getchar();
do
{
if (number == p->date.num)
break;
else
p = p->next;
} while (p != NULL);
if (p == NULL)
{
printf("\n");
printf("未 找 到 此 书 籍 , 请 核 对 编 号\n");
}
else
{
printf("\n");
printf("编号:%d \t《%s》\t 位置:%s\n", p->date.num, p->date.name, p->date.location);
}
}
printf("* * * * * * * * 查找完成* * * * * * * *\n\n");
}
/*主菜单
*/
int Main_menu()
{
system("cls");
printf("* * * * * HPE图书馆 * * * * *\n");
printf("\n");
printf(" A . 管 理 员 入 口\n");
printf("\n");
printf(" B . 借 书 \n");
printf("\n");
printf(" C . 还 书 \n");
printf("\n");
printf(" D . 查 看 图 书 信 息\n");
printf("\n");
printf(" E . 退出\n");
printf("* * * * * * * * * * * * * * * *\n");
char server;
printf("请 选 择 你 所 需 要 的 服 务 :");
do
{
server = getchar();
get_only_oneworld(); //清楚字符缓存区,只让getchar识别第一个字符
switch (server)
{
case 'A': manage_menu(); break;
case 'B':borrow_book(L); break;
case 'C':return_book(L); break;
case 'D': all_book(L); break;
case 'E': break;
default:printf("\t\t\t\t\t\t\t\t\t请 选 择 你 所 需 要 的 服 务 :");
}
} while (server != 'E' && server != 'A' && server != 'B' && server != 'C' && server != 'D');
return 0;
}
/*管理员菜单
*/
int manage_menu()
{
system("cls");
printf("* * * * * 管理员选项 * * * * *\n");
printf("A . 图 书 入 库\n");
printf("\n");
printf("B . 修 改 或 删 除 图 书 信 息\n");
printf("\n");
printf("C . 返 回 主 菜 单\n");
printf("* * * * * * * * * * * * * * *\n");
char server1;
do
{
printf(" *请选择你所需要的服务* :");
server1 = getchar();
get_only_oneworld(); //清楚字符缓存区,只让getchar识别第一个字符
switch (server1)
{
case 'A':putin_book(L); break;
case 'B':change_book_information(L); break;
case 'C': Main_menu(); break;
default:printf("输入错误!!!\n");
}
} while (server1 != 'A'&& server1 != 'B'&& server1 != 'C');
return 0;
}
/*返回选项
*/
int Return_operation()
{
char i;
printf("*********** 1.返回主菜单\n");
printf("*********** 2.结束\n");
do
{
printf("# 请 输 入 你 的 选 项 # :");
i = getchar(); //清楚字符缓存区,只让getchar识别第一个字符
get_only_oneworld();
switch (i)
{
case '1':Main_menu(); break;
case '2':break;
default:printf("输入错误!!!\n");
}
} while (i != '1' && i != '2');
return 0;
}
// 显示图书菜单
void all_book(struct book_date *head)
{
L = head;
void Statistical_books(struct book_date *); //统计图书馆书籍(借出和库存)
system("cls");
printf("* * * * * * * * 书籍目录 * * * * * * * *\n\n");
Statistical_books(L);
printf(" (A) 显 示 借 出 书 籍\n");
printf(" (B) 显 示 库 存 书 籍\n");
printf(" (C) 预 览 图 书\n");
printf(" (D) 返 回 上 一 步\n");
printf("* * * * * * * * * * * * * * * * * * * *\n");
char server;
do
{
printf("# 请 输 入 您 的 选 项 # :");
server = getchar();
get_only_oneworld();
switch (server)
{
case 'A': lend_book(L); break;
case 'B': now_book(L); break;
case 'C': put_date(L); break;
case 'D': Main_menu(); break;
default:printf("输入错误!!!\n");
}
} while (server != 'D');
}