图书管理系统

#include<stdio.h>
#include<stdlib.h>      //提供malloc函数开辟链表空间
#include<string.h>
#include<time.h>        //获得当地时间,作为图书存入时间
#define SIZE 40         //图书名称的大小
struct Book* head =NULL;//链表的首地址!!
/*首地址一定要给他初始化为NULL!!不然会乱指!!*/
struct Book* prev,*current;//记录前一个结构地址和后一个结构地址

struct Time{
    int year;
    int month;
    int day;
    int hour;
    int min;
};
//入库时间的结构,用来存储当地时间
struct Book{
    char bkname[SIZE];//书名
    char writer[SIZE];//作者名
    int number;//图书编号
    float price;//图书价格
    struct Time btime;//存入时间
    struct Book* next;//访问链表下一个结构
};
//图书信息的结构
int num =0;//用来记录图书的数量
int BookNumber =15300;

int main()
{
    void Meau();
    int Input();//使用链表输入图书信息并返回choice的值做接下来的操作
    int Output();//输出图书列表
    int Search_book();//按图书查询
    int Search_writer();//按作者查询
    int Sort_price();//价格排序
    int Delete_book();//按入库时间查询
    int choice;

    system("clear");
    Meau(); 
    printf("您的操作是:");
    scanf("%d",&choice);
    while(getchar()!='\n')
        continue;
    while(choice !='\0'){
        if(choice <0 || choice >6){
            printf("\n请输入正确的操作!(0-6)\n");
            scanf("%d",&choice);//记住要重新给choice赋值,不然输入错误后会无限循环
            while(getchar()!='\n')continue;
        }
        else
            switch(choice){
                case 0: choice ='\0';break;
                case 1: choice =Input();break;
                case 2: choice =Output();break;
                case 3: choice =Search_book();break;
                case 4: choice =Search_writer();break;
                case 5: choice =Sort_price ();break;
                case 6: choice =Delete_book();break;
                default:;
            }
    }
    system("clear");
    printf("\n欢迎下次使用!");
    current =head;
    while(current !=NULL){
        free(current);
        current =current->next;
    }
    return 0;
}
void Meau()
{

    printf("***********************************************************\n");
    printf("*               *欢迎进入图书管理系统*                    *\n");
    printf("*               **********************                    *\n");
    printf("*                                                         *\n");
    printf("*       1):录入图书              2):图书列表              *\n");
    printf("*       3):查询图书              4):查询作者              *\n");
    printf("*       5):按价格排序            6):删除图书              *\n");
    printf("*                                0):退出                  *\n");
    printf("*                                                         *\n");
    printf("*                                                         *\n");
    printf("***********************************************************\n");
}
int Input()
{   /**********************/
    /*获得系统中的当地时间*/
    /**********************/
    time_t timep;//生命一个time_t结构的变量timep
    struct tm *p;//声明一个存储当地时间地址的指针变量
    time(&timep);//获得时间
    p =localtime(&timep);//获得p结构的时间(tm结构:int tm_year,int tm_mon...

    char input[SIZE];//用来判断输入的书名是否为空,空的话就停止输入
    int fchoice;//返回给主函数一个操作

    system("clear");
    puts("请输入第一本书的信息:");
    /**********************/
    /*使用链表输入图书信息*/
    /**********************/
    printf("书    名:     ");
    while (fgets (input,SIZE,stdin)!=NULL && input[0] !='\n'){
        for(int i=0;input[i++]!='\0';)
            if(input[i]=='\n')
                input[i]='\0';
        current = (struct Book* )malloc(sizeof(struct Book));
        if(NULL == current){
            puts("内存分配错误!");
            exit(EXIT_FAILURE);
        }
        /*判断是否为链表头*/
        if(NULL ==head)
            head = current;
        else
        /*将此时的链表地址放到上一个链表的节点处*/
            prev->next = current;
        /*将最后结构中的next指向空的内存*/
        current->next = NULL;
        strcpy(current->bkname,input);
        current->number =BookNumber ++;//编号为输入顺序
        printf("作    者:     ");
        fgets(current->writer,SIZE,stdin);
        for(int i =0;current->writer[i++] !='\0';)
        if( '\n'== current->writer[i]) current->writer[i] ='\0';
        printf("价    格:     ");
        scanf("%f",&current->price);
        while(getchar()!='\n')
            continue;
        printf("编    号:     %d\n",current->number);
        /****************************************/
        /*将tm的时间结构中的值赋值给图书入库时间*/
        /****************************************/
        current->btime.year =1899+p->tm_year;
        current->btime.month =1 +p->tm_mon;
        current->btime.day =p->tm_mday;
        current->btime.hour =p->tm_hour;
        current->btime.min =p->tm_min;
        printf("入库时间:       %d年%d月%d日 %d时%d分\n",current->btime.year,current->btime.month,current->btime.day,current->btime.hour,current->btime.min);
        puts("请输入下一本书的信息:");
        printf("书    名:     ");
        prev =current;
        num++;
    }
    system("clear");//清屏
    puts("录入图书完毕");
    Meau();
    printf("您接下来的操作是:");
    scanf("%d",&fchoice);
    while(getchar()!='\n')continue;
    fflush(stdin);
    system("clear");
    return fchoice;//返回一个操作
}
//输出图书列表,传入链表的首地址head
int Output()
{
    int fchoice;

    if(NULL ==head){
        system("clear");
        printf("暂时没有图书入库\n");
    }
    else
        printf("以下是入库图书列表,入库图书共计%d本\n\n",num);

    current = head;
    while(current !=NULL){
        printf("编    号:     %d\n",current->number);
        printf("书    名:     %s\n",current->bkname);
        printf("作    者:     %s\n",current->writer);
        printf("价    格:     $%.2f\n",current->price);
        printf("入库时间:       %d年%d月%d日 %d时%d分\n",current->btime.year,current->btime.month,current->btime.day,current->btime.hour,current->btime.min);
        printf("***********************************************************\n");
        current =current->next;
    }
    Meau();
    printf("您接下来要进行的操作是:");
    scanf("%d",&fchoice);
    while(getchar()!='\n')continue;
    system("clear");
    Meau();
    return fchoice;//返回一个操作
}
int Search_writer()//按作者查询
{
    int fchoice;
    char bwriter[SIZE];//要查询的作者
    char y_n;//判断是否继续查询

    while (1){
        system("clear");
        printf("\n请输入您要查找的作者姓名:");

        //去除因为使用fgets存入数组中的\n
        fgets(bwriter,SIZE,stdin);
        for(int i =0;bwriter[i++] !='\0';)
            if( '\n'== bwriter[i]) bwriter[i] ='\0';

        current =head;
        if(current ==NULL)printf("书库中暂时没有存书\n");
        while(current != NULL){
            int right =1;//用来判断是否有该作者信息,1为有,0为无
            int i =0;
            /*模糊查询作者姓名,输入头几个字母就能查询到符合信息的作者*/
            while(bwriter[i] !='\0'){//只检查输入者输入的前几个字母在书库中是否有匹配的作者姓名
                if(bwriter[i] == current->writer[i])
                    right =1;

                else {
                    right =0;break;//**********************************
                }                  //right为0则没有这作者信息,1则输出*  
                i++;               //**********************************
            }
            if(right ==1){
                printf("编    号:     %d\n",current->number);
                printf("书    名:     %s\n",current->bkname);
                printf("作    者:     %s\n",current->writer);
                printf("价    格:     $%.2f\n",current->price);
                printf("入库时间:       %d年%d月%d日 %d时%d分\n",current->btime.year,current->btime.month,current->btime.day,current->btime.hour,current->btime.min);
                printf("***********************************************************\n");
                break;  //没有break则会继续执行下面的语句
            } 
            if(NULL ==current->next && 0== right)               //right为0时则没有此作者
                printf("书库中暂时没有该作者信息\n");
        current =current->next;
        }
        /*判断客户是否需要重新查询,y为继续循环,n为跳出循环*/
        printf("是否继续查询(y or n)?        ");
        while(scanf("%c",&y_n)!=1 || (y_n !='y' && y_n !='n')){ //在输入非字符数据或y_n不为y或n时提示错误操作
            while(getchar()!='\n')continue;
            printf("请输入正确的操作!(y or n)  ");
        }
        if('n' == y_n)break;
        while(getchar()!='\n')continue;                         //这句一定不能省略,不然当第二次循环时残存的回车键会被读入fgets里
    }
    system("clear");
    Meau();//菜单
    /*返回一个操作*/
    printf("您的操作是:");
    scanf("%d",&fchoice);
    while(getchar()!='\n')continue;
    return fchoice;
}
/************/
/*按图书查询*/
/************/
int Search_book()
{
    int fchoice;
    char sbook[SIZE];//要查询的图书
    char y_n;//判断是否继续查询

    while (1){
        system("clear");
        printf("\n请输入您要查找的图书:");
        /*去除数组里的换行符*/
        fgets(sbook,SIZE,stdin);
        for(int i =0;sbook[i++] !='\0';)
            if( '\n'== sbook[i]) sbook[i] ='\0';

        current =head;
        if(current ==NULL)printf("书库中暂时没有存书\n");

        /************************/
        /*遍历书库查询符合的信息*/
        /************************/

        while(current != NULL){
            int right =1;//用来判断是否有该图书信息,1为有,0为无
            int i =0;
        /*模糊查询图书,输入头几个字母就能查询到符合信息的所有图书*/
            while(sbook[i] !='\0'){//只检查输入者输入的前几个字母在书库中是否有匹配的图书
                if(sbook[i] == current->bkname[i])
                    right =1;

                else {
                    right =0;break;
                }
                i++;
            }
            if(right ==1){
                printf("编    号:     %d\n",current->number);
                printf("书    名:     %s\n",current->bkname);
                printf("作    者:     %s\n",current->writer);
                printf("价    格:     $%.2f\n",current->price);
                printf("入库时间:       %d年%d月%d日 %d时%d分\n",current->btime.year,current->btime.month,current->btime.day,current->btime.hour,current->btime.min);
                printf("***********************************************************\n");
                break; //没有break则会继续执行下面的语句
            } 
            if(NULL ==current->next && 0== right)//right为0时则没有此作者
                printf("书库中暂时没有该图书\n");
        current =current->next;
        }
        /****************************************************/
        /*判断客户是否需要重新查询,y为继续循环,n为跳出循环*/
        /****************************************************/
        printf("是否继续查询(y or n)?        ");
        while(scanf("%c",&y_n)!=1 || (y_n !='y' && y_n !='n')){ //在输入非字符数据或y_n不为y或n时提示错误操作
            while(getchar()!='\n')continue;
            printf("请输入正确的操作!(y or n)  ");
        }
        if('n' == y_n)break;
        while(getchar()!='\n')continue;//这句一定不能省略,不然当第二次循环时残存的回车键会被读入fgets里然后开头为换行符则结束循环
    }
    system("clear");
    Meau();//菜单
    /*返回一个操作*/
    printf("您的操作是:");
    scanf("%d",&fchoice);
    return fchoice;

}
/******************/
/*按照价格进行排序*/
/******************/
int Sort_price()
{
    system("clear");
    int fchoice;
    int k;//选择排序法用
    struct Book s_price[num];//num的初始值为0,通过过链表的创建操作已被赋予新值 

    /*将链表中的数据赋值给变长数组s_price结构数组中*/
    int i=0;
    current =head;
    while(current !=NULL){

        s_price[i] =*current;
        i++;
        current =current->next;
    }

    /*按照结构数组中的价格排序*/
    for(int i=0;i <num- 1;i ++){
        k =i;
        for(int j=i +1;j <num;j ++)
            if(s_price[k].price > s_price[j].price)k =j;
        if(k !=i){
            struct Book t;

            t =s_price[i];
            s_price[i] =s_price[k];
            s_price[k] =t;
            }
    }
    /*输出排序后的结果*/
    for(int i=0;i<num;i++){
        printf("编    号:     %d\n",s_price[i].number);
        printf("书    名:     %s\n",s_price[i].bkname);
        printf("作    者:     %s\n",s_price[i].writer);
        printf("价    格:     $%.2f\n",s_price[i].price);
        printf("入库时间:       %d年%d月%d日 %d时%d分\n",s_price[i].btime.year,s_price[i].btime.month,s_price[i].btime.day,s_price[i].btime.hour,s_price[i].btime.min);
        printf("***********************************************************\n");
    }
    Meau();//菜单
    /*返回一个操作*/
    printf("您的操作是:");
    scanf("%d",&fchoice);
    while(getchar()!='\n')continue;
    return fchoice;
}
/**********/
/*删除图书*/
/**********/
int Delete_book()
{
    int fchoice;
    int delete_num;//要删除的图书的编号
    struct Book* previ;//记录上一个链表的地址
    struct Book* dele;//记录要删除的图书的地址
    char y_n;

    while(1){

        printf("以下是入库图书列表,入库图书共计%d本\n\n",num);

        current = head;
        while(current !=NULL){
            printf("编    号:     %d\n",current->number);
            printf("书    名:     %s\n",current->bkname);
            printf("作    者:     %s\n",current->writer);
            printf("价    格:     $%.2f\n",current->price);
            printf("入库时间:       %d年%d月%d日 %d时%d分\n",current->btime.year,current->btime.month,current->btime.day,current->btime.hour,current->btime.min);
            printf("***********************************************************\n");
            current =current->next;
        }
        printf("请输入您要删除的图书的编号,返回主页请按q:");
        if(scanf("%d",&delete_num)){
            while(getchar()!='\n')continue;

            if(delete_num < 15300 ){
                system("clear");
                printf("书库中没有该编号存书,请重新输入\n");
                continue;
            }
         } else {
             getchar();         //吸收非数字以及回车符,不然返回主页时会将q和回车输入到fchoice中
             system("clear");
             Meau();            //菜单
             /*返回一个操作*/
             printf("您的操作是:");
             scanf("%d",&fchoice);
             while(getchar()!='\n')continue;
             return fchoice;
         }
        /*删除链表有以下几种情况:
         * 1.只有一本书即num=1时
         * 2.删除第一本书即删除head表头时
         * 3.删除表尾
         * 4.删除中间的链表
         * 要注意的是保证上一个链表能够连接到下下一个链表*/    

        previ =head;
        /*书库中只有一本书的情况下删除图书*/
        if(delete_num ==previ->number && 1==num && NULL ==previ->next){
            printf("您要删除的图书为:\n");
            printf("编    号:     %d\n",previ->number);
            printf("书    名:     %s\n",previ->bkname);
            printf("作    者:     %s\n",previ->writer);
            printf("价    格:     $%.2f\n",previ->price);
            printf("入库时间:       %d年%d月%d日 %d时%d分\n",previ->btime.year,previ->btime.month,previ->btime.day,previ->btime.hour,previ->btime.min);
            printf("是否继续操作(y or n)");
            scanf("%c",&y_n);
            while(getchar()!='\n')continue;

            if('y' ==y_n){
                free(previ);
                previ =NULL;
                head = NULL;        //只有一本书且被删除时记得把表头指向空指针,避免再次输出列表导致野指针的出现(还会列出删除前的书目
                system("clear");
                printf("图书已删除,书库已无存书\n");
                num-=1;
                Meau();//菜单
                /*返回一个操作*/
                printf("您的操作是:");
                scanf("%d",&fchoice);
                while(getchar()!='\n')continue;
                return fchoice;
            } else if('n'==y_n){
                system("clear");
                printf("已取消操作\n");
                continue;
            } else {
                system("clear");
                printf("输入错误,返回删除页面");
                continue;
            }
        }

        //用来判断书库中有无该编号图书,有为1,无为0
        int Pd =0;
        do {
            if(delete_num ==previ->number || delete_num ==previ->next->number){     //使用"||"避免影响删除最后一个链表时的判断
                Pd =1;  break;
            }
            previ =previ->next;
        } while(previ->next !=NULL);

        if(0==Pd){
            system("clear");
            printf("书库中无此存书\n");
            continue;
        }

        // 删除第一本书即删除head表头时
        if(previ ==head && NULL !=previ->next && delete_num == previ->number){
            printf("您要删除的图书为:\n");
            printf("编    号:     %d\n",previ->number);
            printf("书    名:     %s\n",previ->bkname);
            printf("作    者:     %s\n",previ->writer);
            printf("价    格:     $%.2f\n",previ->price);
            printf("入库时间:       %d年%d月%d日 %d时%d分\n",previ->btime.year,previ->btime.month,previ->btime.day,previ->btime.hour,previ->btime.min);
            printf("是否继续操作(y or n)");
            scanf("%c",&y_n);
            while(getchar()!='\n')continue;

            if('y' ==y_n){
                previ =previ->next;
                free(head);     //释放原表头内存
                head =previ;    //给第二个链表内容赋值给表头,成为新表头
                system("clear");
                printf("图书已删除,");
                num-=1;
            } else if('n'==y_n){
                system("clear");
                printf("已取消操作\n");
                continue;
            } else {
                system("clear");
                printf("输入错误,返回删除页面");
                continue;
            }
        }

        else{
            previ =head;
            while(previ->next !=NULL){

                /*删除表尾*/
                if(delete_num ==previ->next->number && NULL ==previ->next->next){
                    printf("您要删除的图书为:\n");
                    printf("编    号:     %d\n",previ->next->number);
                    printf("书    名:     %s\n",previ->next->bkname);
                    printf("作    者:     %s\n",previ->next->writer);
                    printf("价    格:     $%.2f\n",previ->next->price);
                    printf("入库时间:       %d年%d月%d日 %d时%d分\n",previ->next->btime.year,previ->next->btime.month,previ->next->btime.day,previ->next->btime.hour,previ->next->btime.min);
                    printf("是否继续操作(y or n)");
                    scanf("%c",&y_n);
                    while(getchar()!='\n')continue;

                    if('y' ==y_n){
                        free(previ->next);
                        previ->next =NULL;
                        system("clear");
                        printf("图书已删除\n");
                        num-=1;
                        break;
                    } else if('n'==y_n){
                        system("clear");
                        printf("已取消操作\n");
                        break;
                    } else {
                        system("clear");
                        printf("输入错误,返回删除页面\n");
                        break;
                    }
                }

                /*删除链表中间的内容*/
                if(delete_num ==previ->next->number){
                    printf("您要删除的图书为:\n");
                    printf("编    号:     %d\n",previ->next->number);
                    printf("书    名:     %s\n",previ->next->bkname);
                    printf("作    者:     %s\n",previ->next->writer);
                    printf("价    格:     $%.2f\n",previ->next->price);
                    printf("入库时间:       %d年%d月%d日 %d时%d分\n",previ->next->btime.year,previ->next->btime.month,previ->next->btime.day,previ->next->btime.hour,previ->next->btime.min);
                    printf("是否继续操作(y or n)");
                    scanf("%c",&y_n);
                    while(getchar()!='\n')continue;

                    if('y' ==y_n){
                        dele =previ->next;
                        previ->next =previ->next->next; //删除该链表后使前后链表相连
                        free(dele);                     //释放删除的链表空间(dele记录了删除的链表地址)
                        system("clear");
                        printf("图书已删除\n");
                        num-=1;
                        break;
                    }else if('n'==y_n){
                        system("clear");
                        printf("已取消操作\n");
                        break;
                    }else{
                        system("clear");
                        printf("输入错误,返回删除页面\n");
                        break;
                    }
                }

                previ =previ->next;
            }
        }
    }
    system("clear");
    Meau();//菜单
    /*返回一个操作*/
    printf("您的操作是:");
    scanf("%d",&fchoice);
    return fchoice;
}
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,可以了解到图书管理系统的系统架构是通过多种视图来描述系统的各个主要方面,并记录了设计人员对系统构架方面做出的重要决策。此外,还提到了使用面向对象的思想编程实现图书管理系统的功能,包括增删查找。 根据这些信息,可以给出以下回答: 图书管理系统的系统架构是通过多种视图来描述系统的各个主要方面。这些视图可以包括逻辑视图、物理视图、过程视图等。逻辑视图描述了系统的功能和数据结构,物理视图描述了系统的硬件和网络配置,过程视图描述了系统的流程和交互。 设计人员在系统构架方面做出了重要决策,这些决策可能涉及到系统的模块划分、数据存储方式、通信协议等。这些决策的目标是确保系统的可靠性、可扩展性和性能。 使用面向对象的思想编程实现图书管理系统可以提供更好的代码组织和复用性。通过将系统的功能划分为不同的对象和类,可以更好地管理和维护系统的代码。同时,面向对象的编程还可以提供更好的封装性和抽象性,使系统的设计更加灵活和可扩展。 以下是一个简单的图书管理系统的系统架构示例: - 逻辑视图:包括图书管理模块、用户管理模块、借阅管理模块等。 - 物理视图:包括服务器、数据库、网络设备等。 - 过程视图:包括用户登录流程、图书借阅流程、图书归还流程等。 通过这样的系统架构,可以实现图书管理系统的各项功能,并提供良好的用户体验和系统性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值