C——图书管理系统

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值