mian.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include "menu.h"
#include "tools.h"
#include "user.h"
#include "def.h"
#include "selent.h"
int main()
{
book_info_initliaized();
rlist_from_file(user_file);
rbookstream_from_file(book_stream_data);
do
{
start_menu();
}
while(start_menu_selent());
do
{
main_menu();
printf("%c::\n",this->mode);
}
while(main_menu_selent());
wbookstream_to_file(book_stream_data);
wlist_to_file(user_file);
book_info_end();
return 0;
}
meun.h
#ifndef MENU_H_
#define MENU_H_
#include "stdbool.h"
#include "user.h"
//main menu
void main_menu();
//user management menu
void user_man_menu();
void reader_info_change_menu();
void user_info_change_menu();
//reader management menu
void reader_man_menu();
//book management menu
void book_man_menu();
//book stream system menu
void book_stream_menu();
//menu of find some info of book
void book_view_menu();
//register menu
void reg_menu();
//register mode menu
void regmode_menu();
void start_menu();
void book_info_change_menu();
void book_info_serch_menu();
#endif //MENU_H_
menu.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "menu.h"
#include "def.h"
#include "unistd.h"
#include "tools.h"
#include "def.h"
void main_menu()
{
system("clear");
printf("+-----------------------+\n");
printf("\t1.用户管理\n");
printf("\t2.读者管理\n");
printf("\t3.图书管理\n");
printf("\t4.图书流通管理\n");
printf("\t5.退出系统\n");
printf("+-----------------------+\n");
}
//_1
void user_man_menu()
{
system("clear");
printf("+-----------------------+\n");
printf("\t1.用户信息输入\n");
printf("\t2.用户信息修改.\n");
printf("\t3.用户信息删除\n");
printf("\t4.用户信息显示\n");
printf("\t5.返回主菜单\n");
printf("+-----------------------+\n");
}
void user_info_change_menu()
{
system("clear");
printf("+-----------------------+\n");
printf("\t1.修改 id\n");
printf("\t2.修改密码\n");
printf("\t3.修改权限\n");
printf("\t4.退出\n");
printf("+-----------------------+\n");
}
void reader_info_change_menu()
{
system("clear");
printf("+-----------------------+\n");
printf("\t1.姓名\n");
printf("\t2.地址\n");
printf("\t3.电话号码\n");
printf("\t4.退出\n");
printf("+-----------------------+\n");
}
//_2
void reader_man_menu()
{
system("clear");
printf("+-----------------------+\n");
printf("\t1.读者信息输入\n");
printf("\t2.读者信息修改\n");
printf("\t3.读者信息删除\n");
printf("\t4.读者信息查询\n");
printf("\t5.读者信息显示\n");
printf("\t6.返回主菜单\n");
printf("+-----------------------+\n");
}
//_3
void book_man_menu()
{
system("clear");
printf("+-----------------------+\n");
printf("\t1.图书信息输入\n");
printf("\t2.图书信息修改\n");
printf("\t3.图书信息查询\n");
printf("\t4.汇总统计\n");
printf("\t5.返回主菜单\n");
printf("+-----------------------+\n");
}
void book_view_menu()
{
system("clear");
printf("+-----------------------+\n");
printf("\t1.按书名号查询\n");
printf("\t2.按书名查询\n");
printf("\t3.按作者查询\n");
printf("\t4.按出版社查询\n");
printf("\t5.返回主菜单\n");
printf("+-----------------------+\n");
}
//_4
void book_stream_menu()
{
system("clear");
printf("+-----------------------+\n");
printf("\t1.借书处理\n");
printf("\t2.还书处理\n");
printf("\t3.返回主菜单\n");
printf("+-----------------------+\n");
}
void regmode_menu()
{
system("clear");
printf("+----------模式---------+\n");
printf("\t0.教工");
printf("\t1.学生\n");
printf("\t2.图书管理员\n");
printf("\t3.系统管理员\n");
printf("+-----------------------+\n");
}
void start_menu()
{
system("clear");
printf("+-----------------------+\n");
printf("1.\t登陆\n");
printf("2.\t注册\n");
printf("3.\t退出\n");
printf("+-----------------------+\n");
}
void book_info_change_menu()
{
system("clear");
printf("+-----------------------+\n");
printf("\t1.修改藏书量\n");
printf("\t2.修改借书量\n");
printf("\t3.退出\n");
printf("+-----------------------+\n");
}
void book_info_serch_menu()
{
system("clear");
printf("+-----------------------+\n");
printf("\t1.按书号查询\n");
printf("\t2.按书名查询\n");
printf("\t3.按作者查询\n");
printf("\t4.按出版社查询\n");
printf("\t5.返回\n");
printf("+-----------------------+\n");
}
tools.h
#ifndef TOOLS_H_
#define TOOLS_H_
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "user.h"
#include "book.h"
char getch();
char getche();
//登陆
const bool login(User *);
//设置密码
char * get_pass(const char *);
const bool set_password(User * user);
//判断密码密码是否正确
inline static const bool judge_password(const char *str1, const char *str2)
{
if(strcmp(str1,str2)==0)
return true;
else
return false;
}
//清空垃圾字符
inline static void eatline()
{
while(getchar() != '\n')
continue;
}
//注册
bool reg(int);
//判断是否是合法学工号
bool is_id(unsigned);
bool set_mode(User * user);
bool set_id(User *user);
bool set_name(User *user);
//设置用户的单位
bool set_place(User * user);
//设置用户电话号码
void set_phone_number(User * user);
//函数功能,指定一个文件,返回一个指针
//此指针为用户链表的头指针
User * read_from_list(const char *);
//将链表写入文件中
bool wlist_to_file(const char * const);
User *rlist_from_file(const char *const file_name);
//用户信息输入
bool user_info_input();
User * user_is_have(User *, const unsigned);
bool user_delete();
bool user_info_change();
//读者
bool reader_info_input();
bool reader_info_change();
//读者信息删除和用户信息删除公用一个函数
User * reader_info_serch(unsigned id);
void reader_info_view();
int reader_name_compare(const void *,const void *);
void list_to_array(NameAndPointe *);
void print_reader(User *);
void book_info_input();
bool book_info_change();
bool book_info_serch();
void book_col();
bool set_book_id(Book *);
bool set_book_name(Book *);
bool set_book_author(Book *);
bool set_book_pub(Book *);
bool set_book_tot(Book *);
bool set_book_borred_num(Book *);
bool book_info_change();
void book_info_view(Book *);
Book * book_is_have(const char * id);
int name_is_hava(const char * name);
int author_is_have(const char * author);
int pub_is_have(const char * pub);
bool book_name_serch();
bool book_author_serch();
bool book_pub_serch();
unsigned get_mal_num(unsigned tot);
void book_info_initliaized();
void book_info_end();
bool book_bor();
bool book_ret();
BookIO * is_bored(const unsigned id, const char * const book_name);
void rbookstream_from_file(const char * const file_name);
void wbookstream_to_file(const char * const);
#endif //TOOLS_H_
tools.c
#include "tools.h"
#include "user.h"
#include "menu.h"
#include "def.h"
#include "selent.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
char getche()
{
char ch;
system("stty -icanon");
ch = getchar();
system("stty icanon");
return ch;
}
char getch()
{
char ch;
system("stty -echo");
ch = getche();
system("stty echo");
return ch;
}
//查看链表中是否有某一个id
//如果没有返回空指针,否则返回对应节点的前驱节点
User * user_is_have(User * head,const unsigned id)
{
User * bef_link = head;
User * link = head->next;
while(link!=NULL)
{
if(id == link->id)
return bef_link;
else
{
bef_link = bef_link->next;
link = link -> next;
}
}
return NULL;
}
//获得密码,返回i一个指向密码字符串的指针,无回显
char * get_pass(const char * info)
{
static char pass[30];
printf("%s",info);
system("stty -echo");
scanf("%s",pass);
getchar();
system("stty echo");
return pass;
}
//登陆,成功返回真值
//给一个头指针
const bool login(User * head)
{
unsigned _id;
User * _this;
printf("请输入用户id\n");
scanf("%u",&_id);
while((_this = user_is_have(head,_id))== NULL)
{
puts("还没有注册\n请重新输入id(输入0退出):");
scanf("%u",&_id);
if(_id == 0)
return false;
}
_this = _this->next;
int flag = 4;
while(--flag)
{
char *pass = get_pass("请输入密码:");
printf("\n");
if(strcmp(_this->password,pass)==0)
{
this = _this;
return true;
}
}
return false;
}
/*
设置用户密码
传入一个用户指针
成功返回true 否则返回false
*/
const bool set_password(User * user)
{
char * pass1 = get_pass("请输入密码:");
char * pass2 = get_pass("\n请确认密码:");
if(strcmp(pass1,pass2) != 0)
{
printf("两次输入的密码不一致\n");
return false;
}
else if(strlen(pass1) != 8)
{
printf("密码长度必须为八位数\n");
return false;
}
strcpy(user->password,pass1);
printf("\n设置密码成功,是否要查看(y/n)");
char ch;
ch = getch();
printf("\n");
if(ch == 'y'||ch == 'Y')
{
puts(user->password);
}
return true;
}
/*
判断id是否合法
传入一个id
合法 true 否则 false
*/
bool is_id(unsigned id)
{
int flag = 0;
while(id)
{
++flag;
id /= 10;
}
if(flag == 8)
return true;
else
return false;
}
//set_user method
//参数 要改变的节点指针
//成功返回true
bool set_name(User * user)
{
char temp[50];
printf("请输入姓名:");
scanf("%s",temp);
getchar();
if(strlen(temp)>=20)
{
printf("名字过长");
return false;
}
strcpy(user->name,temp);
//printf("set name is : %s", user->name)
return true;
}
bool set_place(User * user)
{
char place[50];
printf("请输入单位:");
scanf("%s",place);
getchar();
if(strlen(place)>=30)
{
printf("请输入合法的字符串\n");
return false;
}
else
{
strcpy(user->place,place);
return true;
}
}
void set_phone_number(User * user)
{
printf("请输入联系方式:");
scanf("%lld",&user->phone_num);
eatline();
}
bool set_id(User * user)
{
unsigned id;
printf("请输入用户账号(学号\\工号)\n");
scanf("%u",&id);
eatline();
if(is_id(id) == false)
{
printf("请输入合法id\n");
return false;
}
if(user_is_have(g_user_list_head,id) != NULL)
{
printf("该用户已经存在\n");
return false;
}
user->id = id;
return true;
}
//成功返回true
bool set_mode(User * user)
{
char ch;
char *pass;
printf("模式:");
ch = getch();
printf("\n");
if(ch == '0' && user->mode != '0')
{
puts("您现在是教工");
user->mode = '0';
user->able_bro = 10;
user->bored_num = 0;
++reader_tot;
}
else if(ch == '1' && user->mode != '1')
{
puts("您现在是学生");
user->mode = '1';
user->able_bro = 5;
user->bored_num = 0;
++reader_tot;
}
else if(ch == '2')
{
pass = get_pass("请输入验证密码:");
if(strcmp(pass,able_bookman) == 0)
{
user->mode = '2';
puts("现在您是图书管理员");
}
else
{
puts("密码错误");
return false;
}
}
else if(ch =='3')
{
pass = get_pass("请输入验证密码:");
if(strcmp(pass,able_admin) == 0)
{
user->mode = '3';
puts("现在您是系统管理员");
}
else
{
return false;
}
}
return true;
}
bool reg(int mode)
{
User * puser = (User*)malloc(sizeof(User));
if(puser == NULL)
{
perror("存储空间不足\n");
free(puser);
return false;
}
while(!set_id(puser))
{
puts("请重新输入id");
}
while(!set_password(puser))
{
puts("请重新设置密码");
}
//读者注册不进入,直接为模式1
//用户注册进入
if(mode)
{
while(!set_mode(puser))
{
puts("请重新设置");
}
}
else
{
printf("模式:(0/1)");
char ch;
ch = getche();
while(ch != '1' && ch != '0')
{
printf("请正确输入");
ch = getche();
}
if(ch == '1')
{
puser->mode = '1';
puser->able_bro = 5;
}
else
{
puser->mode = '0';
puser->able_bro = 10;
}
++reader_tot;
}
//读者模式进入
//用户模式不进入
if(puser->mode == '1' || puser->mode == '0')
{
while(!set_name(puser))
{
puts("请重新输入名字");
}
while(!set_place(puser))
{
puts("请重新设置地址");
}
set_phone_number(puser);
}
puser->next = g_user_list_head->next;
g_user_list_head->next = puser;
return true;
}
//此指针为用户链表的头指针
User *rlist_from_file(const char *const file_name)
{
FILE * fp;
if((fp = fopen(file_name,"rb"))== NULL)
{
printf("打开文件失败\n");
exit(1);
}
g_user_list_head = (User *)malloc(sizeof(User));
g_user_list_head -> next = NULL;
//头插法创建链表
//不读第一个头指针
while(!feof(fp))
{
char ch = getc(fp);
if(ch == EOF) break;
else fseek(fp,-1L,SEEK_CUR);
User * node = (User *)malloc(sizeof(User));
fread(node,sizeof(User),1,fp);
if(node->mode =='0' || node->mode =='1')
{
++reader_tot;
//printf("name is : %s \nplace is : % s", node->name, node->place);
}
node ->next = g_user_list_head->next;
g_user_list_head->next = node;
}
fclose(fp);
return g_user_list_head;
}
bool wlist_to_file(const char * file_name)
{
FILE * fp;
if((fp = fopen(file_name,"wb"))== NULL)
{
printf("打开文件失败\n");
return false;
}
User * link = g_user_list_head->next;
while(link != NULL)
{
fwrite(link,sizeof(User),1,fp);
link = link ->next;
}
fclose(fp);
return true;
}
void user_info_view(User * head)
{
User * link = head ->next;
printf("id\t\t密码\t\t用户类型\n");
while(link != NULL)
{
printf("%d\t",link->id);
printf("%s\t",link->password);
printf("%c\n",link->mode);
link = link->next;
}
getch();
}
bool user_delete()
{
unsigned del_id;
printf("请输入要删除的id(0 exit):");
scanf("%u",&del_id);
if(del_id == 0)
return true;
User * _this = user_is_have(g_user_list_head,del_id);
if(_this == NULL)
{
puts("用户不存在");
return false;
}
User * bef_link = _this;
_this = _this->next;
if(_this->mode == '1'|| _this->mode == '0')
--reader_tot;
bef_link->next = _this->next;
_this->next = NULL;
free(_this);
return true;
}
bool user_info_input()
{
User * user = (User *)malloc(sizeof(User));
if(!set_id(user))
return false;
if(!set_password(user))
return false;
if(!set_mode(user))
return false;
user->next = g_user_list_head->next;
g_user_list_head ->next = user;
return true;
}
bool user_info_change()
{
user_info_change_menu();
printf("请输修改的id");
unsigned id;
scanf("%u",&id);
User * _this;
if(!is_id(id))
{
printf("不是合法id");
return false;
}
if((_this = user_is_have(g_user_list_head,id)) == NULL)
{
printf("该用户不存在");
return false;
}
_this = _this->next;
if(this->mode != '3' && id != this->id)
{
printf("只能修改自己的账号\n");
}
if(user_info_change_menu_selent(_this))
{
return true;
}
else
return false;
}
int reader_name_compare(const void * name1, const void * name2)
{
NameAndPointe *n1 = (NameAndPointe *)name1;
NameAndPointe *n2 = (NameAndPointe *)name2;
return strcmp(n1->name,n2->name);
}
bool reader_info_change()
{
reader_info_change_menu();
printf("请输入修改的id");
unsigned id;
scanf("%u",&id);
User * _this;
if(!is_id(id))
{
printf("不是合法id");
return false;
}
if((_this = user_is_have(g_user_list_head,id)) == NULL)
{
printf("该用户不存在");
return false;
}
_this = _this->next;
if(reader_info_change_menu_selent(_this))
{
return true;
}
else
return false;
}
void print_reader(User * user)
{
printf("%u\t",user->id);
printf("%s\t",user->name);
printf("%s\t",user->place);
printf("%lld\t",user->phone_num);
printf("%u\t\t",user->able_bro);
printf("%u\n",user->bored_num);
}
void reader_info_view()
{
printf("一共有%u个读者\n",reader_tot);
NameAndPointe * nap = (NameAndPointe *)malloc(sizeof(NameAndPointe) * reader_tot);
list_to_array(nap);
qsort(nap,reader_tot,sizeof(NameAndPointe),reader_name_compare); //int (*)(void *, void *)
printf("读者号\t\t读者名\t单位\t联系方式\t可借书数\t已借书数\n");
for(int i=0; i<reader_tot; ++i)
{
print_reader(nap[i].user);
}
getch();
free(nap);
}
void list_to_array(NameAndPointe * arrnap)
{
User * node;
node = g_user_list_head->next;
for(int i=0; node != NULL; node = node->next)
{
if(node->mode == '1' || node->mode == '0')
{
strcpy(arrnap[i].name, node->name);
arrnap[i].user = node;
++i;
}
}
}
bool set_book_id(Book * book)
{
char id[20];
printf("请输入书号:");
scanf("%s",id);
getch();
if(book_is_have(id) != NULL)
{
return false;
}
if(strlen(id)>=10)
return false;
else
{
strcpy(book->book_id,id);
return true;
}
}
bool set_book_tot(Book * book)
{
int tot;
printf("请输入藏书量:");
scanf("%d",&tot);
eatline();
if(tot <= 0)
return false;
else
{
book->tot = tot;
return true;
}
}
bool set_book_name(Book * book)
{
char temp[30];
printf("请输入书名:");
scanf("%s",temp);
getchar();
if(strlen(temp)>=20)
{
return false;
}
else
{
strcpy(book->name,temp);
return true;
}
}
bool set_book_author(Book * book)
{
char temp[30];
printf("请输入作者:");
scanf("%s",temp);
getchar();
if(strlen(temp)>=20)
{
return false;
}
else
{
strcpy(book->author,temp);
return true;
}
}
bool set_book_pub(Book * book)
{
char temp[30];
printf("请输入出版社:");
scanf("%s",temp);
getchar();
if(strlen(temp)>=20)
{
return false;
}
else
{
strcpy(book->pubhouse,temp);
return true;
}
}
bool set_book_borred_num(Book * book)
{
int num;
printf("请输入已借书数:");
scanf("%d",&num);
if(num <0 || num > book->tot)
return false;
else
{
book->borred_num = num;
return true;
}
}
//对图书信息进行输入
void book_info_input(Book * book)
{
while(!set_book_id(book))
{
puts("请重新输入图书号");
}
while(!set_book_name(book))
{
puts("请重新输入书名");
}
while(!set_book_author(book))
{
puts("请重新输入作者");
}
while(!set_book_pub(book))
{
puts("请重新输入出版社");
}
while(!set_book_tot(book))
{
puts("请重新输入藏书量");
}
while(!set_book_borred_num(book))
{
puts("请重新输入已借书数");
}
book->num_id = book_tot;
book->borred_tot = book->borred_num;
int flag = name_is_hava(book->name);
if(flag == -1)
{
strcpy(name_table[name_tot].key_name,book->name);
name_table[name_tot].first_idx = book_tot;
name_table[name_tot].len = 1;
book->name_next = -1;
++name_tot;
}
else
{
book->name_next = name_table[flag].first_idx;
name_table[flag].first_idx = book_tot;
++name_table[flag].len;
}
flag = author_is_have(book->author);
if(flag == -1)
{
strcpy(author_table[author_tot].key_name,book->author);
author_table[author_tot].first_idx = book_tot;
author_table[author_tot].len = 1;
book->autor_next = -1;
++author_tot;
}
else
{
book->autor_next = author_table[flag].first_idx;
author_table[flag].first_idx = book_tot;
++author_table[flag].len;
}
flag = pub_is_have(book->pubhouse);
if(flag == -1)
{
strcpy(pub_table[pub_tot].key_name,book->pubhouse);
pub_table[pub_tot].first_idx = book_tot;
pub_table[pub_tot].len = 1;
book->pub_next = -1;
++pub_tot;
}
else
{
book->pub_next = pub_table[flag].first_idx;
pub_table[flag].first_idx = book_tot;
++pub_table[flag].len;
}
++book_tot;
}
bool book_info_change(Book * book)
{
book_info_change_menu();
char sel;
sel = getch();
switch(sel)
{
case '1' :
set_book_tot(book);
break;
case '2' :
set_book_borred_num(book);
break;
case '3' :
return false;
default :
break;
}
return true;
}
void book_info_initliaized()
{
FILE * main_fp, * name_fp, * author_fp, * pub_fp, *col_fp;
if((main_fp = fopen(book_file,"r")) == NULL)
{
puts("打开图书主文件失败");
exit(1);
}
if((name_fp = fopen(book_name_table,"r")) == NULL)
{
puts("打开名字索引文件失败");
exit(1);
}
if((author_fp = fopen(book_author_table,"r")) == NULL)
{
puts("打开作者索引文件失败");
exit(1);
}
if((pub_fp = fopen(book_pub_table,"r")) == NULL)
{
puts("出版社索引文件打开失败");
exit(1);
}
if((col_fp = fopen(book_col_file,"r")) == NULL)
{
perror("en book_col file failed");
exit(1);
}
book_main_table = (Book *)malloc(sizeof(Book) * get_mal_num(book_tot));
name_table = (Idx *)malloc(sizeof(Idx) * get_mal_num(name_tot));
author_table = (Idx *)malloc(sizeof(Idx) * get_mal_num(author_tot));
pub_table = (Idx *)malloc(sizeof(Idx) * get_mal_num(pub_tot));
fscanf(main_fp,"%d",&book_tot);
fscanf(name_fp,"%d",&name_tot);
fscanf(author_fp,"%d",&author_tot);
fscanf(pub_fp,"%d",&pub_tot);
for(int i=0;i<book_tot;++i)
{
fscanf(main_fp,"%u%s%s%s%s%u%u%d%d%d",&book_main_table[i].num_id,
book_main_table[i].book_id, book_main_table[i].name,
book_main_table[i].author, book_main_table[i].pubhouse,
&book_main_table[i].tot, &book_main_table[i].borred_num,
&book_main_table[i].name_next, &book_main_table[i].autor_next, &book_main_table[i].pub_next);
fscanf(col_fp,"%u",&book_main_table[i].borred_tot);
}
for(int i=0;i<name_tot;++i)
{
fscanf(name_fp,"%s%d%d",name_table[i].key_name, &name_table[i].first_idx, &name_table[i].len);
}
for(int i=0;i<author_tot;++i)
{
fscanf(author_fp,"%s%d%d",author_table[i].key_name, &author_table[i].first_idx, &author_table[i].len);
}
for(int i=0;i<pub_tot;++i)
{
fscanf(pub_fp,"%s%d%d",pub_table[i].key_name, &pub_table[i].first_idx, &pub_table[i].len);
}
fclose(main_fp);
fclose(name_fp);
fclose(author_fp);
fclose(pub_fp);
fclose(col_fp);
}
void book_info_end()
{
FILE * main_fp, * name_fp, * author_fp, * pub_fp, *col_fp;
if((main_fp = fopen(book_file,"w")) == NULL)
{
puts("打开图书主文件失败");
exit(1);
}
if((name_fp = fopen(book_name_table,"w")) == NULL)
{
puts("打开名字索引文件失败");
exit(1);
}
if((author_fp = fopen(book_author_table,"w")) == NULL)
{
puts("打开作者索引文件失败");
exit(1);
}
if((pub_fp = fopen(book_pub_table,"w")) == NULL)
{
puts("出版社索引文件打开失败");
exit(1);
}
if((col_fp = fopen(book_col_file,"w")) == NULL)
{
perror("en book_col file failed");
exit(1);
}
fprintf(main_fp,"%u\n",book_tot);
fprintf(name_fp,"%u\n",name_tot);
fprintf(author_fp,"%u\n",author_tot);
fprintf(pub_fp,"%u\n",pub_tot);
for(int i=0;i<book_tot;++i)
{
fprintf(main_fp,"%d%10s%10s%10s%10s\t%-u\t%-u\t%d\t%d\t%d\n",book_main_table[i].num_id,
book_main_table[i].book_id, book_main_table[i].name,
book_main_table[i].author, book_main_table[i].pubhouse,
book_main_table[i].tot, book_main_table[i].borred_num,
book_main_table[i].name_next, book_main_table[i].autor_next, book_main_table[i].pub_next);
fprintf(col_fp,"%u ", book_main_table[i].borred_tot);
}
for(int i=0;i<name_tot;++i)
{
fprintf(name_fp,"%s %d %d\n",name_table[i].key_name, name_table[i].first_idx, name_table[i].len);
}
for(int i=0;i<author_tot;++i)
{
fprintf(author_fp,"%s %d %d\n", author_table[i].key_name, author_table[i].first_idx, author_table[i].len);
}
for(int i=0;i<pub_tot;++i)
{
fprintf(pub_fp,"%s %d %d\n", pub_table[i].key_name, pub_table[i].first_idx, pub_table[i].len);
}
fclose(main_fp);
fclose(name_fp);
fclose(author_fp);
fclose(pub_fp);
fclose(col_fp);
}
Book * book_is_have(const char * id)
{
for(int i = 0;i<book_tot;++i)
{
if(strcmp(book_main_table[i].book_id,id) == 0)
{
return book_main_table + i;
}
}
return NULL;
}
int name_is_hava(const char * name)
{
int i = name_tot -1;
getchar();
for(;i>=0;--i)
{
if(strcmp(name_table[i].key_name,name) == 0)
{
break;
}
}
getchar();
return i;
}
int author_is_have(const char * author)
{
int i = author_tot - 1;
for(;i>=0;--i)
{
if(strcmp(author_table[i].key_name,author) == 0)
{
break;
}
}
return i;
}
int pub_is_have(const char * pub)
{
int i = pub_tot-1;
for(;i>=0;--i)
{
if(strcmp(pub_table[i].key_name,pub) == 0)
{
break;
}
}
return i;
}
void book_info_view(Book * book)
{
printf("%s\t",book->book_id);
printf("%s\t",book->name);
printf("%s\t",book->author);
printf("%s\t",book->pubhouse);
printf("%u\t%u\n",book->tot,book->borred_num);
}
bool book_name_serch()
{
char name[20];
printf("请输入要查找的书名:");
scanf("%s",name);
getchar();
int i=name_tot-1;
for(;i>=0;--i)
{
if(strcmp(name_table[i].key_name,name) == 0)
{
break;
}
}
if(i == -1) return false;
i = name_table[i].first_idx;
printf("书号\t书名\t作者\t出版社\t藏书量\t已借阅\n");
while(i != -1)
{
book_info_view(book_main_table+i);
i = book_main_table[i].name_next;
}
getch();
return true;
}
bool book_author_serch()
{
char author[20];
printf("请输入想要查找的作者:");
scanf("%s",author);
getchar();
int i = author_tot - 1;
for(;i>=0;--i)
{
if(strcmp(author_table[i].key_name,author) == 0)
{
break;
}
}
if(i == -1) return false;
i = author_table[i].first_idx;
printf("书号\t书名\t作者\t出版社\t藏书量\t已借阅\n");
while(i != -1)
{
book_info_view(book_main_table+i);
i = book_main_table[i].autor_next;
}
getch();
return true;
}
bool book_pub_serch()
{
char pub[20];
printf("请输入想要查找的出版社: ");
scanf("%s",pub);
getchar();
int i = pub_tot - 1;
for(;i>=0;--i)
{
if(strcmp(pub_table[i].key_name,pub) == 0)
{
break;
}
}
if(i == -1) return false;
i = pub_table[i].first_idx;
printf("书号\t书名\t作者\t出版社\t藏书量\t已借阅\n");
while(i != -1)
{
book_info_view(book_main_table+i);
i = book_main_table[i].pub_next;
}
getch();
return true;
}
bool book_info_serch()
{
char id[10];
Book * serch_ans;
book_info_serch_menu();
char sel;
sel = getch();
switch(sel)
{
case '1' :
printf("请输入要查找的书号: ");
scanf("%s",id);
getchar();
if((serch_ans = book_is_have(id)) == NULL)
{
puts("没有这本书");
usleep(3 * lapse_time);
}
else
{
printf("书号\t书名\t作者\t出版社\t藏书量\t已借阅\n");
book_info_view(serch_ans);
getch();
}
break;
case '2' :
if(!book_name_serch())
{
puts("没有这本书");
usleep(3 * lapse_time);
}
break;
case '3' :
if(!book_author_serch())
{
puts("没有这本书");
usleep(3 * lapse_time);
}
break;
case '4' :
if(!book_pub_serch())
{
puts("没有这本书");
usleep(3 * lapse_time);
}
break;
case '5' :
return false;
default :
break;
}
return true;
}
unsigned get_mal_num(const unsigned tot)
{
if(tot == 0)
return 50;
if(tot < 50 )
return tot + 20;
if(tot < 100)
return tot + 40;
if(tot >= 100)
return (unsigned)(tot + tot * 0.3);
}
bool book_ret()
{
BookIO * bookio;
char book_id[10];
unsigned reader_id;
printf("请输入读者号和书号:\n");
scanf("%d %s",&reader_id, book_id);
getchar();
if((bookio = is_bored(reader_id, book_id)) == NULL)
{
printf("借书信息不匹配");
return false;
}
printf("请输入还书日期:");
char date[20];
scanf("%s",date);
getchar();
strcpy(bookio->ret_date,date);
Book * book;
User * user;
book = book_is_have(book_id);
user = user_is_have(g_user_list_head,reader_id);
if(user != NULL)
{
user = user->next;
--user->bored_num;
}
--book->borred_num;
return true;
}
bool book_bor()
{
BookIO * bookio = (BookIO *)malloc(sizeof(BookIO));
printf("请输入借书的读者号:");
unsigned id;
scanf("%u",&id);
eatline();
User * user;
if((user = user_is_have(g_user_list_head,id)) == NULL)
{
printf("没有此用户");
return false;
}
user = user->next;
if(user->mode == '2' || user->mode == '3')
{
printf("该用户不是读者");
return false;
}
if(user->bored_num >= user->able_bro)
{
printf("借书数量达到上限");
return false;
}
printf("请输入要借阅的书号: ");
char book_id[10];
scanf("%s",book_id);
getchar();
Book * book;
if((book = book_is_have(book_id)) == NULL)
{
printf("没有这本书:");
return false;
}
if(book->borred_num + 1 > book->tot)
{
printf("这本书已经被全部借阅");
return false;
}
++bookio_tot;
user->bored_num++;
++book->borred_tot;
bookio->reader_id = id;
book->borred_num++;
printf("请输入借书日期:");
char date[20];
scanf("%s",date);
getchar();
strcpy(bookio->book_id,book_id);
strcpy(bookio->bor_date,date);
strcpy(bookio->ret_date,"null");
strcpy(bookio->remark,"null");
bookio->next = g_bookstream_list_head->next;
g_bookstream_list_head->next = bookio;
return true;
}
void rbookstream_from_file(const char * const file_name)
{
FILE * fp;
if((fp = fopen(file_name,"r")) == NULL)
{
perror("打开流通文件文件失败");
exit(1);
}
g_bookstream_list_head = (BookIO *)malloc(sizeof(BookIO));
g_bookstream_list_head->next = NULL;
BookIO * node;
fscanf(fp,"%u",&bookio_tot);
for(int i=0;i<bookio_tot;++i)
{
node = (BookIO *)malloc(sizeof(BookIO));
fscanf(fp,"%u",&node->reader_id);
//printf("%u ",node->reader_id);
fscanf(fp,"%s",node->book_id);
//printf("%s ",node->book_id);
fscanf(fp,"%s",node->bor_date);
//printf("%s ",node->bor_date);
fscanf(fp,"%s",node->ret_date);
//printf("%s ",node->ret_date);
fscanf(fp,"%s",node->remark);
// printf("%s ",node->remark);
node->next = g_bookstream_list_head->next;
g_bookstream_list_head->next = node;
}
fclose(fp);
}
void wbookstream_to_file(const char * const file_name)
{
FILE * fp;
if((fp = fopen(file_name,"w")) == NULL)
{
perror("打开图书流通文件失败");
exit(1);
}
BookIO * node = g_bookstream_list_head->next;
fprintf(fp,"%u\n",bookio_tot);
while(node != NULL)
{
fprintf(fp,"%u %s %s %s %s\n",node->reader_id,node->book_id,node->bor_date,node->ret_date,node->remark);
node = node->next;
}
fclose(fp);
}
BookIO * is_bored(const unsigned reader_id, const char * const book_id)
{
BookIO * booknode = g_bookstream_list_head->next;
while(booknode != NULL)
{
if(booknode->reader_id == reader_id && strcmp(booknode->book_id,book_id) == 0 && (strcmp(booknode->ret_date,"null") == 0))
return booknode;
booknode = booknode->next;
}
return NULL;
}
void book_col()
{
int flag = 0;
unsigned max = 0;
for(int i=0;i<book_tot;++i)
{
if(book_main_table[i].borred_tot > max)
{
flag = i;
max = book_main_table[i].borred_tot;
}
}
printf("最受欢迎的图书:");
printf("%s\t%s\t%s\t%s",book_main_table[flag].book_id,book_main_table[flag].name,book_main_table[flag].author,book_main_table[flag].pubhouse);
getch();
}
user.h
#ifndef USER_H_
#define USER_H_
#include <string.h>
typedef struct User
{
char mode;
unsigned id;
char name[20];
char place[30];
unsigned long long phone_num;
char password[9];
unsigned able_bro;
struct User * next;
unsigned bored_num;
}User;
typedef struct NameAndPointe
{
char name[20];
User * user;
}NameAndPointe;
#endif //USER_H_
book.h
#ifndef BOOK_H_
#define BOOK_H_
typedef struct Book
{
unsigned num_id;
char book_id[10];
char name[20];
char author[20];
char pubhouse[30];
unsigned tot;
unsigned borred_num;
unsigned borred_tot;
//索引下标
int name_next;
int autor_next;
int pub_next;
}Book;
typedef struct Index
{
char key_name[20];
unsigned first_idx;
unsigned len;
}Idx;
typedef struct BookIO
{
unsigned reader_id;
char book_id[20];
char bor_date[20];
char ret_date[20];
char remark[20];
struct BookIO * next;
}BookIO;
#endif //BOOK_H_
def.h
#ifndef DEF_H_
#define DEF_H_
#include "user.h"
#include "book.h"
const unsigned lapse_time ;
const char * const user_file;
const char * const book_file;
const char * const able_admin;
const char * const able_bookman;
const char * const reader_file;
const char * const book_name_table;
const char * const book_author_table;
const char * const book_pub_table;
const char * const book_stream_data;
const char * const book_col_file;
//list
User * g_user_list_head;
BookIO * g_bookstream_list_head;
//用于存放登陆的节点
User *this;
unsigned reader_tot;
//book
unsigned book_tot;
unsigned name_tot;
unsigned author_tot;
unsigned pub_tot;
unsigned bookio_tot;
enum {READERREG = 0, USERREG = 1};
Book * book_main_table;
Idx * name_table;
Idx * author_table;
Idx * pub_table;
#endif // DEF_H_
def.c
#include "def.h"
const unsigned lapse_time = 1000 * 50;
const char * const user_file = "/home/qimg/Desktop/code/LIbraryManagementSystem/userdata";
const char * const book_file = "/home/qimg/Desktop/code/LIbraryManagementSystem/bookdata";
const char * const book_name_table = "/home/qimg/Desktop/code/LIbraryManagementSystem/nametable";
const char * const book_author_table = "/home/qimg/Desktop/code/LIbraryManagementSystem/authortable";
const char * const book_pub_table = "/home/qimg/Desktop/code/LIbraryManagementSystem/pubtable";
const char * const book_stream_data = "/home/qimg/Desktop/code/LIbraryManagementSystem/bookstream";
const char * const book_col_file = "/home/qimg/Desktop/code/LIbraryManagementSystem/bookborredtot";
const char * const able_admin = "iamadmin";
const char * const able_bookman = "ibookmam";
unsigned reader_tot = 0;
//book
unsigned book_tot = 0;
unsigned name_tot = 0;
unsigned author_tot = 0;
unsigned pub_tot = 0;
unsigned bookio_tot = 0;
selent.h
#ifndef SELENT_H_
#define SELENT_H_
#include <stdbool.h>
#include "tools.h"
//注册登陆界面选项函数
bool start_menu_selent();
bool main_menu_selent();
bool user_man_menu_selent();
bool user_info_change_menu_selent(User * user);
bool reader_man_menu_selent();
bool reader_info_change_menu_selent(User * user);
bool book_man_menu_selent();
bool book_info_change_menu_selent(Book * book);
bool book_stream_menu_selent();
#endif //SELENT_H_
selent.c
#include <unistd.h>
#include "selent.h"
#include "menu.h"
#include "tools.h"
#include "def.h"
//选择登陆并且成功返回false 没有成功返回true
//选择3直接退出程序
//选择注册只返回true
bool start_menu_selent()
{
char sel;
sel = getch();
switch(sel)
{
case '1' :
if(login(g_user_list_head))
{
return false;
}
break;
case '2' :
reg(USERREG);
break;
case '3' :
wlist_to_file(user_file);
exit(0);
default :
break;
}
return true;
}
bool main_menu_selent()
{
char sel;
sel = getche();
switch(sel)
{
case '1' :
while(user_man_menu_selent());
break;
case '2' :
if(this->mode == '2')
while(reader_man_menu_selent());
else
{
puts("权限不够");
usleep(3 * lapse_time);
}
break;
case '3' :
while(book_man_menu_selent());
break;
case '4' :
if(this->mode == '2')
{
while(book_stream_menu_selent());
}
else
{
printf("权限不够");
usleep(3 * lapse_time);
}
break;
case '5' :
return false;
default :
break;
}
return true;
}
bool user_man_menu_selent()
{
char sel;
user_man_menu();
sel = getch();
switch(sel)
{
case '1' :
if(this->mode == '3')
reg(USERREG);
else
{
printf("权限不够\n");
}
break;
case '2' :
user_info_change();
break;
case '3' :
if(this->mode == '3')
user_delete();
else printf("权限不够\n");
break;
case '4' :
if(this->mode == '3')
user_info_view(g_user_list_head);
else printf("权限不够\n");
break;
case '5' :
return false;
default :
break;
}
return true;
}
bool user_info_change_menu_selent(User * user)
{
eatline();
bool flag = false;
user_info_change_menu();
if(user->mode == '0' || user->mode == '1')
flag = true;
char sel;
sel = getch();
switch(sel)
{
case '1' :
if(this->mode == '3')
set_id(user);
else printf("权限不够\n");
break;
case '2' :
set_password(user);
break;
case '3' :
if(this->mode == '3')
{
set_mode(user);
if(flag &&(user->mode == '2' || user->mode == '3'))
--reader_tot;
}
else printf("权限不够\n");
break;
case '4' :
return false;
default :
break;
}
return true;
}
bool reader_info_change_menu_selent(User * user)
{
eatline();
reader_info_change_menu();
char sel;
sel = getch();
switch(sel)
{
case '1' :
set_name(user);
break;
case '2' :
set_place(user);
break;
case '3' :
set_phone_number(user);
break;
case '4' :
return false;
}
return true;
}
bool reader_man_menu_selent()
{
unsigned id;
User * _this;
reader_man_menu();
char sel;
reader_man_menu();
sel = getch();
switch(sel)
{
case '1' :
reg(READERREG);
break;
case '2' :
reader_info_change();
break;
case '3' :
user_delete();
break;
case '4' :
printf("请输入查找的id");
scanf("%u",&id);
eatline();
//reader_info_serch();
if((_this = user_is_have(g_user_list_head,id)) == NULL)
{
printf("这个用户不存在\n");
usleep(4* lapse_time);
}
else
{
_this = _this->next;
printf("读者号\t\t读者名\t单位\t\t联系方式\t\t\t可借书数\t\t已借书数\n");
print_reader(_this);
getch();
}
break;
case '5' :
reader_info_view(g_user_list_head);
break;
case '6' :
return false;
default :
break;
}
return true;
}
bool book_man_menu_selent()
{
char sel;
Book * book;
book_man_menu();
sel = getch();
char id[20];
switch(sel)
{
case '1' :
if(this->mode == '2')
{
book_info_input(book_main_table+book_tot);
}
else
{
puts("权限不够");
usleep(3 * lapse_time);
}
break;
case '2' :
if(this->mode == '2')
{
printf("请输入要修改的书号:");
scanf("%s",id);
getchar();
if((book = book_is_have(id)) == NULL)
{
printf("没有这本书");
return false;
}
else
{
book_info_change(book);
}
}
else
{
puts("权限不够");
usleep(3 * lapse_time);
}
break;
case '3' :
while(book_info_serch());
break;
case '4' :
book_col();
break;
case '5' :
return false;
default :
break;
}
return true;
}
bool book_info_change_menu_selent(Book * book)
{
book_info_change_menu();
char sel;
sel = getch();
switch(sel)
{
case '1' :
set_book_tot(book);
break;
case '2' :
set_book_borred_num(book);
break;
case '3' :
return false;
default :
break;
}
return true;
}
bool book_stream_menu_selent()
{
book_stream_menu();
char sel;
sel = getch();
switch(sel)
{
case '1' :
while(!book_bor());
break;
case '2' :
while(!book_ret());
break;
case '3' :
return false;
default :
break;
}
return true;
}