#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 1024
struct Book *book_pool = NULL;//内存池
int count_book = 0;
struct User *user_pool = NULL;
int count_user = 0;
struct Date{
int year;
int month;
int day;
};
struct Book{
char name[40];//书名
char author[128];//作者
char publisher[40];//出版社
int exist;
struct Date date;//日期
struct Book *next;
};
struct User{
char name[40];//用户名
char cypher[32];//密码
int amount;//借取书本量
struct Date date;//注册日期
struct User *next;
};
void welcome(struct Book **book, struct User **user);//打印欢迎和使用说明
void consumer(void);//打印用户使用说明
void manage(void);//打印管理员使用说明
int log_on(struct User *head);//登录
int administrator(void);//登录管理员
//用户相关的函数
struct User *seek_user(struct User *head);//寻找用户,返回地址
void print_user_one(struct User *head);//根据地址打印用户的信息
void increase(struct User **head);//增加用户
void reduce(struct User **head);//减少用户
void query(struct User *book);//查询用户信息
void modify(struct User *head);//修改用户信息
void display(struct User *head);//显示所有用户信息
//图书相关的函数
struct Book *seek_book(struct Book *head);//寻找图书,返回地址
void print_book_one(struct Book *head);//根据地址打印图书的信息
void insert(struct Book **head);//录入新的图书
void searchEvent(struct Book *book);//查找已有的图书
void change(struct Book **head);//更改已有的图书
void delete(struct Book **head);//删除已有的图书
void print(struct Book *head);//打印所有的图书信息
void enter(struct Book *book, struct User *user);//结束程序时将信息放入文件
void borrow(void);//借书//
void still(void);//还书//
void welcome(struct Book **head_book, struct User **head_user){//打印欢迎和使用说明
FILE *fp1, *fp2;
struct Book *temp_book = NULL, *book;
struct User *temp_user = NULL, *user;
book = *head_book;
user = *head_user;
printf("| 欢迎使用图书馆程序 |\n");
printf("|------ 1:注册 ------|\n");
printf("|------ 2:登录 ------|\n");
printf("|------ 3:退出 ------|\n");
printf("|--------------------|\n");
if ((fp1 = fopen("book.txt", "rb")) == NULL){//fopen获取文件指针
printf("打开文件失败!\n");
exit(EXIT_FAILURE);
}
while (1){
if (book_pool != NULL){//如果内存池非空,直接从里面获取空间
temp_book = book_pool;
book_pool = book_pool->next;
count_book--;
}
else{//如果内存池空,使用malloc申请内存
temp_book = (struct Book *)malloc(sizeof(struct Book));
if(temp_book == NULL){
printf("内存分配失败了。\n");
exit(EXIT_FAILURE);
}
}
fread(temp_book, sizeof(struct Book), 1, fp1);// 将文件数据读取出来
if (feof(fp1)){
if (temp_user == NULL){
free(temp_book);
}
break;
}
if (*head_book != NULL){
temp_book = *head_book;
*head_book = book;
book->next = temp_book;
}
else{
*head_book = book;
book->next = NULL;
}
}
fclose(fp1);//关闭文件!!!!
if ((fp2 = fopen("user.txt", "rb")) == NULL){//fopen获取文件指针
printf("打开文件失败!\n");
exit(EXIT_FAILURE);
}
while (1){
if (user_pool != NULL){//如果内存池非空,直接从里面获取空间
temp_user = user_pool;
user_pool = user_pool->next;
count_user--;
}
else{//如果内存池空,使用malloc申请内存
temp_user = (struct User *)malloc(sizeof(struct User));
if(temp_user == NULL){
printf("内存分配失败了。\n");
exit(EXIT_FAILURE);
}
}
fread(temp_user, sizeof(struct User), 1, fp2);// 将文件数据读取出来
if (feof(fp2)){
if (temp_user == NULL){
free(temp_user);
}
break;
}
if (*head_user != NULL){
temp_user = *head_user;
*head_user = user;
user->next = temp_user;
}
else{
*head_user = user;
user->next = NULL;
}
}
fclose(fp2);
}
void consumer(void){//打印用户使用说明
printf("| 欢迎使用图书馆参观程序 |\n");
printf("|--- 1:查找已有图书 -----|\n");
printf("|--- 2:显示当前图书库 ---|\n");
printf("|--- 3:借取已有图书 -----|\n");
printf("|--- 4:归还借取图书 -----|\n");
printf("|--- 5:进入管理员模式 ---|\n");
printf("|--- 6:退出图书馆程序 ---|\n");
printf("|----------------------|\n");
}
void manage(void){//打印管理员使用说明
printf("| 欢迎使用图书馆管理程序 |\n");
printf("|--- 1:插入新的图书 -----|\n");
printf("|--- 2:更改已有图书 -----|\n");
printf("|--- 3:删除已有图书 -----|\n");
printf("|--- 4:显示当前图书库 ---|\n");
printf("|--- 5:更改用户信息 -----|\n");
printf("|--- 6:查询用户信息 -----|\n");
printf("|--- 7:删除用户信息 -----|\n");
printf("|--- 8:显示用户名单 -----|\n");
printf("|--- 9:退出图书馆程序 ---|\n");
printf("|----------------------|\n");
}
int log_on(struct User *head){//登录/
struct User *user;
char mm[32];
user = seek_user(head);
printf("请输入密码:");
scanf("%s", mm);
while (user != NULL){
if (!strcmp(user->cypher, mm)){
printf("登录成功");
return 1;
}
printf("密码错误,登录失败");
return 0;
}
printf("没有找到帐号,登录失败");
return 0;
}
int administrator(void){
char mm[32];
printf("请输入管理员密码:");
scanf("%s", mm);
if (!strcmp("123456", mm)){
printf("登录成功");
return 1;
}
printf("密码错误,登录失败");
return 0;
}
struct User *seek_user(struct User *head){//寻找用户,返回地址
struct User *target;
char name[40];
printf("请输入用户:");
scanf("%s", name);
target = head;
while (target != NULL && strcmp(target->name, name)){
target = target->next;
}
return target;
}
void print_user_one(struct User *head){//根据地址打印用户的信息
printf("密码:%s\n", head->cypher);
printf("注册日期(aa-bb-cc):%d-%d-%d\n", head->date.year, head->date.month, head->date.day);
printf("借取图书 %d 本", head->amount);
}
void increase(struct User **head){//增加用户/
struct User *user;
struct User *temp;
if (user_pool != NULL){//如果内存池非空,直接从里面获取空间
user = user_pool;
user_pool = user_pool->next;
count_user--;
}
else{//如果内存池空,使用malloc申请内存
user = (struct User *)malloc(sizeof(struct User));
if(user == NULL){
printf("内存分配失败了。\n");
exit(1);
}
}
printf("请输入用户名:");
scanf("%s", user->name);
printf("请设置密码:");
scanf("%s", user->cypher);
printf("请输入注册日期(aa-bb-cc)");
scanf("%d-%d-%d", &user->date.year, &user->date.month, &user->date.day);
user->amount = 0;
if (*head != NULL){
temp = *head;
*head = user;
user->next = temp;
}
else{
*head = user;
user->next = NULL;
}
}
void reduce(struct User **head){//减少用户
struct User *target;//目标
struct User *now;
struct User *temp;//上一次
target = seek_user(*head);// 先找到待删除的节点指针
if (target == NULL){
printf("找不到该用户!\n");
}
else{
now = *head;
temp = NULL;
while (now != NULL && now != target){// current定位到待删除的节>点
temp = now;
now = now->next;
}
if (temp == NULL){// 待删除的节点是第一个节点
*head = now->next;
}
else{// 待删除的节点不是第一个节点
temp->next = now->next;
}
if (count_user < MAX){//判断内存池有没有空位
if (user_pool != NULL){
temp = user_pool;
user_pool = target;
target->next = NULL;
}
else{
user_pool = target;
target->next = NULL;
}
count_user++;
}
else{
free(target);
}
}
}
void query(struct User *head){//查询用户信息
struct User *user;
char name[32];
printf("请输入用户名:");
scanf("%s", name);
user = head;
while (user != NULL){
if (!strcmp(user->name, name)){
break;
}
user = user->next;
}
if(user == NULL){
printf("抱歉,没有找到。\n");
}
else{
print_user_one(user);
}
}
void modify(struct User *head){//修改用户信息/
struct User *target;
char name[32];
target = seek_user(head);// 先找到待更改的节点指针
if (target == NULL){
printf("找不到该用户!\n");
}
else{
printf("请设置用户名:");
scanf("%s", target->name);
printf("请设置密码:");
scanf("%s", target->cypher);
printf("请设置注册日期(aa-bb-cc):");
scanf("%d-%d-%d", &target->date.year, &target->date.month, &target->date.day);
printf("请设置借取图书量:");
scanf("%D", &head->amount);
}
}
void display(struct User *head){//显示所有用户信息/
struct User *now;
now = head;
while (now != NULL){
printf("用户名:%s\n", now->name);
print_user_one(now);
now = now->next;
}
}
//--------------------------图书------------------------------
struct Book *seek_book(struct Book *head){//寻找图书,返回地址
struct Book *target;
char name[40];
printf("请输入书名:");
scanf("%s", name);
target = head;
while (target != NULL && strcmp(target->name, name)){
target = target->next;
}
return target;
}
void print_one(struct Book *head){//根据地址打印图书的信息
printf("作者:%s\n", head->author);
printf("出版社:%s\n", head->publisher);
printf("日期:%d-%d-%d\n", head->date.year, head->date.month, head->date.day);
printf("书籍状态:");
switch (head->exist){
case 1: printf("可借取\n");break;
case 0: printf("不可借取\n");break;
}
}
void insert(struct Book **head){//录入新的图书
struct Book *book;
struct Book *temp;
if (book_pool != NULL){//如果内存池非空,直接从里面获取空间
book = book_pool;
book_pool = book_pool->next;
count_book--;
}
else{//如果内存池空,使用malloc申请内存
book = (struct Book *)malloc(sizeof(struct Book));
if(book == NULL){
printf("内存分配失败了。\n");
exit(1);
}
}
printf("请输入书名:");
scanf("%s", book->name);
printf("请输入作者:");
scanf("%s", book->author);
printf("请输入出版社:");
scanf("%s", book->publisher);
printf("请输入日期(aa-bb-cc):");
scanf("%d-%d-%d", &book->date.year, &book->date.month, &book->date.day);
book->exist = 1;
if (*head != NULL){
temp = *head;
*head = book;
book->next = temp;
}
else{
*head = book;
book->next = NULL;
}
putchar('\n');
}
void searchEvent(struct Book *head){//查找已有的书名
struct Book *book;
char name[32];
printf("请输入书名:");
scanf("%s", name);
book = head;
while (book != NULL){
if (!strcmp(book->name, name)){
break;
}
book = book->next;
}
if(book == NULL){
printf("抱歉,没有找到。\n");
}
else{
print_one(book);
}
}
void change(struct Book **head){//更改
struct Book *target;
char name[32];
target = seek_book(*head);// 先找到待更改的节点指针
if (target == NULL){
printf("找不到该书名!\n");
}
else{
printf("请输入作者:");
scanf("%s", target->author);
printf("请输入出版社:");
scanf("%s", target->publisher);
printf("请输入日期(aa-bb-cc):");
scanf("%d-%d-%d", &target->date.year, &target->date.month, &target->date.day);
printf("是否可借取(1/0):");
scanf("%d", &target->exist);
}
}
void delete(struct Book **head){//删除
struct Book *target;//目标
struct Book *now;
struct Book *temp;//上一次
target = seek_book(*head);// 先找到待删除的节点指针
if (target == NULL){
printf("找不到该书名!\n");
}
else{
now = *head;
temp = NULL;
while (now != NULL && now != target){// current定位到待删除的节点
temp = now;
now = now->next;
}
if (temp == NULL){// 待删除的节点是第一个节点
*head = now->next;
}
else{// 待删除的节点不是第一个节点
temp->next = now->next;
}
if (count_book < MAX){//判断内存池有没有空位
if (book_pool != NULL){
temp = book_pool;
book_pool = target;
target->next = NULL;
}
else{
book_pool = target;
target->next = NULL;
}
count_book++;
}
else{
free(target);
}
}
}
void print(struct Book *head){//打印
struct Book *now;
now = head;
while (now != NULL){
printf("书名:%s\n", now->author);
print_one(now);
now = now->next;
}
}
void enter(struct Book *book, struct User *user){//结束程序时将图书信息放入文件
struct Book *book_temp;
struct User *user_temp;
FILE *fp1, *fp2;
if ((fp1 = fopen("book.txt", "wb")) == NULL){//fopen获取文件指针
printf("打开文件失败!\n");
exit(EXIT_FAILURE);
}
if ((fp2 = fopen("user.txt", "wb")) == NULL){//fopen获取文件指针
printf("打开文件失败!\n");
exit(EXIT_FAILURE);
}
while (book != NULL){
fwrite(book, sizeof(struct Book), 1, fp1);// 将数据写入到文件中,释放内存
book_temp = book;
book = book->next;
free(book_temp);
}
while (user != NULL){
fwrite(user, sizeof(struct User), 1, fp2);// 将数据写入到文件中,释放内存
user_temp = user;
user = user->next;
free(user_temp);
}
fclose(fp1);//关闭文件!!!!
fclose(fp2);
while (user_pool != NULL){//释放内存池
user_temp = user_pool;
user_pool = user_pool->next;
free(user_temp);
}
while (book_pool != NULL){//释放内存池
book_temp = book_pool;
book_pool = book_pool->next;
free(book_temp);
}
}
int main(void){
struct Book *book = NULL;
struct User *user = NULL;
char name[32];
int i;
welcome(&book, &user);
while (1){
printf("\n请输入指令代码:");
scanf("%d", &i);
switch (i){
case 1: increase(&user);break;
case 2: if (log_on(user)){
consumer();
while (1){
printf("\n请输入指令代码:");
scanf("%d", &i);
switch (i){
case 1: searchEvent(book);break;
case 2: ;break;//
case 3: ;break;//
case 4: print(book);break;
case 5:if (administrator()){
manage();
while (1){
printf("\n请输入指令代码:");
scanf("%d", &i);
switch (i){
case 1: insert(&book);break;
case 2: change(&book);break;
case 3: delete(&book);break;
case 4: print(book);break;
case 5: modify(user);break;
case 6: query(user);break;
case 7: reduce(&user);break;
case 8: display(user);break;
case 9: enter(book, user);exit(i);
}
}
}
else{
printf("密码错误\n");
}
break;
case 6: enter(book, user);exit(i);
}
}
}
else{
printf("密码错误\n");
}
break;
case 3: enter(book, user);exit(i);
}
}
return 0;
}