C语言项目搭建-图书管理系统(链表详解)

项目介绍

项目名称图书管理系统


图书管理系统设计与实现项目的背景: 

图书馆人员结构复杂,人员数量有限,涉及方面很广,如果还使用手工操作处理图书借阅问题,工作将非常繁琐,需要大量的人力、物力、财力,极大的浪费了资源,对于图书管理人员来说,图书馆管理包括图书信息管理、图书类别管理、借阅信息管理、管理员信息管理等等。而这些项目在过去靠手工操作,需要手工记录这些事情,不但麻烦,还经常出错,给广大用户带来很多不便,因此,开发这样一套图书馆管理系统软件。让管理员方便的管理图书及用户信息,方便用户查找图书。


系统要实现的功能概述:

(1)用户登录管理员根据用密码进行身份验证登录系统

(2)菜单介绍根据菜单介绍本系统的使用规则

(3)图书信息录入根据编号录入图书信息

(4)图书信息浏览根据编号显示图书信息

(5)图书信息查找根据编号查找图书信息

(6)图书信息修改根据编号修改图书信息

(7)图书信息保存输入图书信息文件存档 

(8)图书信息插入输入图书信息插入系统

(9)图书信息删除:根据图书编号进行删除


目录

项目介绍

用户登录系统

 系统菜单提示

 图书信息录入

 图书信息浏览

 图书信息插入

 图书信息删除

图书信息保存

图书信息查找

图书信息修改

退出管理系统

 主函数的介绍


人生漫长,晴雨交加

但若是心怀热爱,即使岁月荒芜

亦能奔山赴海,静待一树花开

对于这种代码量超百位数的,大家最好养成分模块写代码的习惯: 

我创建了一个.h文件offer.h和两个.c 文件my_offeroffer.c

我的offer.h一般放头文件和结构体类型

my_offer.c文件一个设置主函数main

offer.c文件完善相应的函数接口

这样分工明确,不会混乱,可以提高敲代码的效率哦~


代码的讲解如下:

头文件:

#include <stdio.h>//标准输入输出函数
#include <stdlib.h>//动态内存malloc函数,system函数
#include <string.h>	//strcmp比较字符串函数
#include <assert.h>//断言判断malloc的空间有没有开辟成功,没有成功就产生断点

宏定义: 

#define N 10

结构体:

typedef struct
{
    char num[N];	     //编号
    char namebook[N];	 //名字
    int price;	         //价格
}Book;
typedef struct Lnode
{
    Book date;              //数据域,结构体的嵌套
    struct Lnode* next;     //指针域
}Lnode, * Node;             //指向节点的指针

用户登录系统

void menu2()
{
    int input = 0, count = 0, i = 0;
    char mima[20] = "123";//登入的密码
    char shuru[20] = { 0 };
    system("color F4");
    printf("\t\t\t     **************************************\n");
    printf("\t\t\t     |       *欢迎使用图书管理系统*       |\n");
    printf("\t\t\t     |           *管理员: 小唐*           |\n");
    printf("\t\t\t      ------------------------------------\n");
    printf("请输入管理员密码:\n");
    while ((count = _getch()) != '\r')
    {
        if (count == '\b')
        {
            i--;
            printf("\b \b");
        }
        else
        {
            shuru[i++] = count;
            printf("*");
        }
    }
    shuru[i++] = '\0';
    if (strcmp(mima, shuru) == 0)
    {
        printf("\n密码正确,您已进入系统!\n");
    }
    else
    {
        printf("\n密码错误,请重新输入!\n");
        exit(0);     //输入错误,直接退出
    }
    system("pause");
    system("cls");
}

用户登入系统的代码讲解:

 


1.我们来看这里设置了两个数组,目的就是判断我的输入数组和我的常量密码数组大小是否相等,用strcmp函数来判断,如果相同密码正确则进入管理系统

2.我们这里利用了while去进行getch输入getch输入单个字符是不会显示信息的,但我们按下回车键输入结束,循环停止,' \r '就是回车键的意思

3.' \b '删除键的意思,每当我按下回车键计数器' i '就会减小1

4.相反每当我们输入一个字符计数器' i '增1,并且输出' * '

5.因为是字符数组,所以要留个位置给' \0 '(字符串结束的标志)

6. system("color F4")-改变屏幕颜色

    system("pause")-按任意键进行的函数
    system("cls")-清屏函数

7.exit(0)-关闭所有文件,终止正在执行的进程

这就是我们的登入系统的设置


 系统菜单提示

这是我们的介绍帮助副菜单: 

void assist()
{
    printf("\t\t-------------------------------*系统菜单介绍*--------------------------------------------\n");
    printf("图书馆人员结构复杂,人员数量有限,涉及方面很广,如果还使用手工操作处理图书借阅问题,工作将非常繁琐\n");
    printf("而这些项目在过去靠手工操作,需要手工记录这些事情,不但麻烦,还经常出错\n");
    printf("给广大用户带来很多不便,因此,开发这样一套图书馆管理系统软件\n");
    printf("让管理员方便的管理图书及用户信息,方便用户查找图书\n");
}

这是我们的选择功能主菜单: 

void menu()
{
    printf("\n");
    system("color F4");
    printf("\t\t\t*****************************************************\n");
    printf("\t\t\t*---------------------------------------------------*\n");
    printf("\t\t\t*                   图书管理系统                    *\n");
    printf("\t\t\t*****************************************************\n");
    printf("\t\t\t********************系统功能菜单*********************\n");
    printf("\t\t\t----------------------     --------------------------\n");
    printf("\t\t\t*****************************************************\n");
    printf("\t\t\t**    1、使用帮助菜单   *     2、浏览图书信息      **\n");
    printf("\t\t\t*****************************************************\n");
    printf("\t\t\t**    3、插入图书信息   *     4、删除图书信息      **\n");
    printf("\t\t\t*****************************************************\n");
    printf("\t\t\t**    5、图书信息保存   *     6、退出管理系统      **\n");
    printf("\t\t\t*****************************************************\n");
    printf("\t\t\t**    7、修改图书信息   *     8、查找图书系统     **\n");
    printf("\t\t\t*****************************************************\n");
    printf("\t\t\t*****************************************************\n");
    printf("\t\t\t----------------------     --------------------------\n");
}

系统菜单提示的代码讲解:


这我就不用多说了吧,随大家喜好进行添加

全是printf函数的输出,美化页面的功夫我相信你比我强


 图书信息录入

Node inputbook()                    //输入图书信息(尾插法)
{
    printf("--------------------------*图书录入系统*----------------------------------\n");
    Node L,p,s;                         //设置三个结构体指针变量
    L = (Node)malloc(sizeof(Lnode));    //用malloc开辟头节点L结构体的动态内存
    assert(L);                          //断言判断动态空间是否开辟成功
    s = L;                              //将头节点赋值给s
    int input;                          //定义一个变量input来判断录入图书的数量
    printf("请输入图书数量:");
    scanf("%d", &input);
    while (input--)
    {
        p = (Node)malloc(sizeof(Lnode));      //为p开辟空间也就是创建下一个节点
        assert(p);                            //断言判断空间是否开辟成功
        printf("请输入图书信息>:\n");        //输入基本信息
        printf("*-----------------------*\n");
        printf("请输入图书编号:\n");
        scanf("%s", p->date.num);
        printf("*-----------------------*\n");
        printf("请输入图书名字:\n");
        scanf("%s", p->date.namebook);
        printf("*-----------------------*\n");
        printf("请输入图书价格:\n");
        scanf("%d", &p->date.price);          //因为不是数组所以不用&
        printf("------------------------*您的图书数据已录入系统*-----------------------------------\n");
        system("pause");                      //按任意键
        system("cls");                        //清除屏幕
        p->next = NULL;                       //如果不在录入图书信息就指向NULL
        s->next = p;                          //s指向下一个节点,并将p赋值给s
        s = p;
    }
    return L;                                 //返回给链表头节点L
}

图书信息录入系统的代码讲解: 


1. Node L,p,s:设置三个结构体指针变量

2. L = (Node)malloc(sizeof(Lnode)):用malloc开辟一个结构体的动态内存

3. assert(L):判断L有没有开辟动态内存成功,没有就产生断点

4. p->next = NULL:如果不在录入图书信息就让p的下一个节点指向NULL

5. s->next = p:并将p赋值给s指向的下一个节点 

这里看不懂请不要着急,接下我将进行链表尾插法的详细讲解

链表尾插法: 

核心代码

s = L;
p->next = NULL;
s->next = p;
s = p;
尾插法在结尾插入新节点,只需将末尾节点的指针指向新节点即可

我们先将s指向头指针head

p用来开辟新节点

当节点开辟完毕,让s的下一个节点指向p节点的位置

再使p节点在向后开辟新节点

若后面没有节点则置为NULL


 图书信息浏览

void printbook(Node L)   
{
    Node n;	
    n = L->next;
    printf("------------------------*图书信息显示*------------------------\n");
    while (n)
    {	
        printf("书名:%s\t编号:%s\t价格:%d", n->date.namebook,n->date.num,n->date.price);
        n = n->next;
        printf("\n");
    }
    printf("-----------------------*感谢使用本系统*-----------------------\n");
}

图书信息浏览的代码讲解:


这个就不用我多说了吧:

定义结构体指针定义的变量n,n在指向头节点的下一个节点

n不为NULL时,就执行循环语句的内容

n在指向下一个节点就可以访问下一个节点的内容了


 图书信息插入

void chabook(Node L)
{
    int m, j, n = 0;                          
    Node s, ptr;		                      
    ptr = L;                                          //让定义的结构体指针指向头节点L
    while (ptr != NULL) 	                          //通过遍历算出节点数
    {					    
        ptr = ptr->next;                              //当ptr访问的下一个节点为NULL时,就停止访问
        n++;			  
    }
    printf("请输入将图书插入的位置:\n");
    scanf("%d", &m);
    while (m > n)                                      //如果输入数字大于节点数就会执行以下语句
    {
        printf("输入的位置大于图书数量,请重新输入!\n");
        scanf("%d", &m);
    }
    ptr = L;                                            //让ptr重新指向头节点L
    j = 1; 
    while (ptr && (j < m))                              //循环到插入位置的前一个节点
    {
        ptr = ptr->next;
        j++;
    }
    s = (Node)malloc(sizeof(Lnode));                     //对新节点进行动态内存开辟
    assert(s);                                           //判断s的动态空间开辟有没有成功
    printf("----------------------------*图书插入系统*-----------------------------------------\n");
    printf("请输入图书信息:\n");	 
    printf("\n");
    printf("*-----------------------*\n");
    printf("请输入图书的名字:\n");
    scanf("%s", s->date.namebook);
    printf("*-----------------------*\n");
    printf("请输入图书的编号:\n");
    scanf("%s", s->date.num);
    printf("*-----------------------*\n");
    printf("请输入图书价格:\n");
    scanf("%d", &s->date.price);
    s->next = ptr->next;                //将新结点的next指针指向插入位置后的结点                
    ptr->next = s;                      //将插入位置前结点的next指针指向插入结点                
    printf("——————————————*信息插入成功*-------------------------------------——\n");
}

图书信息插入的代码讲解:


因为讲解在代码注释中已经说过了

接下来我们来解释本环节比较难理解的地方:

    s->next = ptr->next;                //将新结点的next指针指向插入位置后的结点                
    ptr->next = s;                      //将插入位置前结点的next指针指向插入结点   

1.假如我的图书信息想要插入3号位置,那么我的新节点s应该要指向原ptr的指向的下一个位置,也就是新节点的下一个位置

2.然后我的ptr->next链接新节点s,这样新节点就和前后串连了,原来的链条就没用了


 图书信息删除

void freebook(Node L)
{
    int m, n = 0, j;
    Node p, q;                                   
    p = L->next;                                    //让定义的结构体指针指向头节点L
    while (p != NULL)                               //通过遍历算出节点数
    {                                               //当ptr访问的下一个节点为NULL时,就停止访问
        p = p->next;
        n++;
    }
    printf("----------------------------------*图书删除系统*-------------------------------------\n");
    printf("请输入要删除图书的位置:\n");
    scanf("%d", &m);
    while (n < m)                                     //如果输入数字大于节点数就会执行以下语句
    {
        printf("输入的图书超过总数,请重新输入要删除的图书位置:\n");
        scanf("%d", &m);
    }
    p = L; j = 1;                                      //让ptr重新指向头节点L
    while ((p->next) && (j < m))	                   //循环到插入位置的前一个节点
    {
        p = p->next;
        j++;
    }	
    q = p->next;	                                    //q指向指定节点m
    p->next = q->next;	                                //两个节点手拉手
    free(q);	                                        //释放内存空间
    printf("———————-----------————*图书删除成功*—--------------------------—————\n");
}

图书信息删除代码讲解:


因为讲解在代码注释中已经说过了

接下来我们来解释本环节比较难理解的地方:

p->next = q->next;	                      

q的下一个节点赋值给p的下一个节点(手拉手),这样链表就连在一起了

q空间被free函数释放掉后,这个节点就相当于被删除了


图书信息保存

void fopenbook(Node L)
{
    FILE* fp;                                      //定义文件指针FILE* 类型的fp
    Node ptr = L;                                  
    char filename[N];
    printf("------------------------------\n");
    printf("---*请输入你要保存的文件名*---\n");
    printf("------------------------------\n");
    scanf("%s", filename);
    if ((fp = fopen(filename, "wb")) == NULL)      //fopen打开文件,wb为了输出数据,打开一个二进制文件
    {
        printf("------------------------*打开文件失败*---------------------------\n");
        exit(0);                                   //如果fp为NULL就说明打开文件失败,退出文件操作
    }
    while (ptr->next != NULL)                      //while循环遍历整个链表
    {
        printf("------------------------*保存文件成功*---------------------------\n");
        fprintf(fp, "%s\n", ptr->next->date.namebook);    //fprintf格式化输出函数
        fprintf(fp, "%s\n", ptr->next->date.num);         //将链表节点的信息在文件上显示
        fprintf(fp, "%d\n", ptr->next->date.price);
        ptr = ptr->next;                                  //访问下一个节点
    }
    fclose(fp);                                           //关闭文件
    fp = NULL;                                            
}

图书信息保存的代码讲解:


该说的已经打在注释上了,该文件操作有些许复杂,我这几天会整理给大家

接下来我们来讲怎么在VS2022上打开文件

1.首先打开视图,找到我们的解决方案管理器

2.在项目名称后面点击右键选择打开文件

3.找到我们的保存文件

用记事本打开就可以看到啦


图书信息查找

void seebook(Node L)
{
    char num[N];                                
    Node p;
    printf("-----------------------------------*图书查找系统*--------------------------------------------\n");
    printf("请输入查找的图书编号:>\n");
    scanf("%s", num);
    p = L->next;                                 //结构体指针p指向头节点的下一位
    while (p && strcmp(p->date.num, num) != 0)	 //strcmp函数比较两个字符串的大小
    {                                            //如果p不指向NULL,且两个字符串大小不相同就进入循环
        p = p->next;                             //访问下一个节点
    }                                           
    if (p)                                       //现在访问的就是目标节点
    {
        printf("*-----------------------*\n");
        printf("书名:%s\t编号:%s\t价格:%d", p->date.namebook, p->date.num, p->date.price);  //如果不是NULL,就输出节点信息
        printf("*-----------------------*\n");
    }
    else
    {
        printf("该图书信息还没有录入系统!\n");
    }
    printf("------------------------------------*图书查找系统欢迎您*---------------------------------------\n");
}

图书信息查找的代码讲解:


int strcmp ( const char * str1, const char * str2 );

首先我们来介绍一下strcmp函数的主要功能:

1. 常用于比较字符串的大小

2.第一个字符串大于第二个字符串,则返回大于0的值

3.第一个字符串等于第二个字符串,则返回0

4.第一个字符串小于第二个字符串,则返回小于0的值

5.比较两个字符串对应位置上的字符ASCLL码值的大小来判断字符串的大小


1.如果strcmp(p->date.num, num) != 0就说明查找的不是这个节点

p = p->next访问下一个节点

2.如果strcmp(p->date.num, num) == 0就说明查找到的是该节点

就将该节点的图书信息打印出来就好啦


图书信息修改

void editbook(Node L)
{
    char num[N];
    int input = 0;
    Node p;
    printf("-----------------------------------*图书修改系统*--------------------------------------------\n");
    printf("----------------------------\n");
    printf("|-------*1.图书编号*-------|\n");
    printf("|-------*2.图书名字*-------|\n");
    printf("|-------*3.图书价格*-------|\n");
    printf("----------------------------\n");
    printf("请输入查找的图书编号:>\n");
    scanf("%s", num);
    p = L->next;
    while (p && strcmp(p->date.num, num) != 0)	//strcmp函数比较两个字符串的大小
    {
        p = p->next;
    }
    if (p)
    {
        printf("请选择你要修改的图书内容>:\n");
        printf("*-------------------------*\n");
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            printf("-------*修改图书编号*-------\n");
            scanf("%s", p->date.num);
            break;
        case 2:
            printf("-------*修改图书名字*-------\n");
            scanf("%s", p->date.namebook);
            break;
        case 3:
            printf("-------*修改图书价格*-------\n");
            scanf("%d", &p->date.price);
            break;
        default:
            printf("*-------------------------*\n");
            printf("输入错误,重新操作!\n");
            break;
        }
    }
    else
    {
        printf("该图书信息还没有录入系统!\n");
    }
}

图书信息修改的代码讲解: 


这段代码跟图书信息查找有很多相似之处

所以这里并不想重复:

当找到修改节点位置时,用switch选择要修改的图书内容

然后在运用指针p就可以访问当前节点的结构体成员修改图书信息


退出管理系统

void quitbook(Node L)
{
    printf("*-------------------------#您已退出此系统,欢迎下次使用#-------------------------------*\n");
    exit(0);
}

退出管理系统的代码讲解:


当你录入图书完成后,想退出系统就可以用exit(0)退出

这估计是所有项目接口中最简单的一个了吧


 主函数的介绍

int main()
{
    menu2();
    menu();
    Node L;
    L = inputbook();
    int input = 0;
    while (1)
    {
        menu();
        printf("\n*请输入你要进行的图书操作>:\n");
        scanf("%d", &input);
            switch (input)
            {
            case 1:assist(); break;
            case 2:printbook(L); break;
            case 3:chabook(L); break;
            case 4:freebook(L); break;
            case 5:fopenbook(L); break;
            case 6:quitbook(L); break;
            case 7:editbook(L); break;
            case 8:seebook(L); break;
            }
        }
    return 0;
}

主函数main的代码讲解:

这个其实没什么好说的,相信大家都看的懂

主要是swith选择语句加函数调用

但是这样造成了很多重复代码的编写

改进方法:函数指针数组


以下就是整个代码的实现啦:

以上代码旁边都有注释哦,注意查看

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<assert.h>
#define N 20
typedef struct
{
    char num[N];	     
    char namebook[N];	 
    int price;	         
}Book;
typedef struct Lnode
{
    Book date;              
    struct Lnode* next;     
}Lnode, * Node;            
void menu2()
{
    int input = 0, count = 0, i = 0;
    char mima[20] = "123";
    char shuru[20] = { 0 };
    system("color F4");
    printf("\t\t\t     **************************************\n");
    printf("\t\t\t     |       *欢迎使用图书管理系统*       |\n");
    printf("\t\t\t     |           *管理员: 小唐*           |\n");
    printf("\t\t\t      ------------------------------------\n");
    printf("请输入管理员密码:\n");
    while ((count = _getch()) != '\r')
    {
        if (count == '\b')
        {
            i--;
            printf("\b \b");
        }
        else
        {
            shuru[i++] = count;
            printf("*");
        }
    }
    shuru[i++] = '\0';
    if (strcmp(mima, shuru) == 0)
    {
        printf("\n密码正确,您已进入系统!\n");
    }
    else
    {
        printf("\n密码错误,请重新输入!\n");
        exit(0);
    }
    system("pause");
    system("cls");
}
void assist()
{
    printf("\t\t-------------------------------*系统菜单介绍*--------------------------------------------\n");
    printf("图书馆人员结构复杂,人员数量有限,涉及方面很广,如果还使用手工操作处理图书借阅问题,工作将非常繁琐\n");
    printf("而这些项目在过去靠手工操作,需要手工记录这些事情,不但麻烦,还经常出错\n");
    printf("给广大用户带来很多不便,因此,开发这样一套图书馆管理系统软件\n");
    printf("让管理员方便的管理图书及用户信息,方便用户查找图书\n");
}
void menu()
{
    printf("\n");
    system("color F4");
    printf("\t\t\t*****************************************************\n");
    printf("\t\t\t*---------------------------------------------------*\n");
    printf("\t\t\t*                   图书管理系统                    *\n");
    printf("\t\t\t*****************************************************\n");
    printf("\t\t\t********************系统功能菜单*********************\n");
    printf("\t\t\t----------------------     --------------------------\n");
    printf("\t\t\t*****************************************************\n");
    printf("\t\t\t**    1、使用帮助菜单   *     2、浏览图书信息      **\n");
    printf("\t\t\t*****************************************************\n");
    printf("\t\t\t**    3、插入图书信息   *     4、删除图书信息      **\n");
    printf("\t\t\t*****************************************************\n");
    printf("\t\t\t**    5、图书信息保存   *     6、退出管理系统      **\n");
    printf("\t\t\t*****************************************************\n");
    printf("\t\t\t**    7、修改图书信息   *     8、查找图书系统     **\n");
    printf("\t\t\t*****************************************************\n");
    printf("\t\t\t*****************************************************\n");
    printf("\t\t\t----------------------     --------------------------\n");
}
Node inputbook()
{
    printf("--------------------------*图书录入系统*----------------------------------\n");
    Node L, p, s;
    L = (Node)malloc(sizeof(Lnode));
    assert(L);
    s = L;
    int input;
    printf("请输入图书数量:");
    scanf("%d", &input);
    while (input--)
    {
        p = (Node)malloc(sizeof(Lnode));
        assert(p);
        printf("请输入图书信息>:\n");
        printf("*-----------------------*\n");
        printf("请输入图书编号:\n");
        scanf("%s", p->date.num);
        printf("*-----------------------*\n");
        printf("请输入图书名字:\n");
        scanf("%s", p->date.namebook);
        printf("*-----------------------*\n");
        printf("请输入图书价格:\n");
        scanf("%d", &p->date.price);
        printf("------------------------*您的图书数据已录入系统*-----------------------------------\n");
        system("pause");
        system("cls");
        p->next = NULL;
        s->next = p;
        s = p;
    }
    return L;
}
void printbook(Node L)
{
    Node n;
    n = L->next;
    printf("------------------------*图书信息显示*------------------------\n");
    while (n)
    {
        printf("书名:%s\t编号:%s\t价格:%d", n->date.namebook, n->date.num, n->date.price);
        n = n->next;
        printf("\n");
    }
    printf("-----------------------*感谢使用本系统*-----------------------\n");
}
void chabook(Node L)
{
    int m, j, n = 0;
    Node s, ptr;
    ptr = L;
    while (ptr != NULL)
    {
        ptr = ptr->next;
        n++;
    }
    printf("请输入将图书插入的位置:\n");
    scanf("%d", &m);
    while (m > n)
    {
        printf("输入的位置大于图书数量,请重新输入!\n");
        scanf("%d", &m);
    }
    ptr = L;
    j = 1;
    while (ptr && (j < m))
    {
        ptr = ptr->next;
        j++;
    }
    s = (Node)malloc(sizeof(Lnode));
    assert(s);
    printf("----------------------------*图书插入系统*-----------------------------------------\n");
    printf("请输入图书信息:\n");
    printf("\n");
    printf("*-----------------------*\n");
    printf("请输入图书的名字:\n");
    scanf("%s", s->date.namebook);
    printf("*-----------------------*\n");
    printf("请输入图书的编号:\n");
    scanf("%s", s->date.num);
    printf("*-----------------------*\n");
    printf("请输入图书价格:\n");
    scanf("%d", &s->date.price);
    s->next = ptr->next;
    ptr->next = s;
    printf("——————————————*信息插入成功*-------------------------------------——\n");
}
void freebook(Node L)
{
    int m, n = 0, j;
    Node p, q;
    p = L->next;
    while (p != NULL)
    {
        p = p->next;
        n++;
    }
    printf("----------------------------------*图书删除系统*-------------------------------------\n");
    printf("请输入要删除图书的位置:\n");
    scanf("%d", &m);
    while (n < m)
    {
        printf("输入的图书超过总数,请重新输入要删除的图书位置:\n");
        scanf("%d", &m);
    }
    p = L; j = 1;
    while ((p->next) && (j < m))
    {
        p = p->next;
        j++;
    }
    q = p->next;
    p->next = q->next;
    free(q);
    printf("———————-----------————*图书删除成功*—--------------------------—————\n");
}
void fopenbook(Node L)
{
    FILE* fp;
    Node ptr = L;
    char filename[N];
    printf("------------------------------\n");
    printf("---*请输入你要保存的文件名*---\n");
    printf("------------------------------\n");
    scanf("%s", filename);
    if ((fp = fopen(filename, "wb")) == NULL)
    {
        printf("------------------------*打开文件失败*---------------------------\n");
        exit(0);
    }
    while (ptr->next != NULL)
    {
        printf("------------------------*保存文件成功*---------------------------\n");
        fprintf(fp, "%s\n", ptr->next->date.namebook);
        fprintf(fp, "%s\n", ptr->next->date.num);
        fprintf(fp, "%d\n", ptr->next->date.price);
        ptr = ptr->next;
    }
    fclose(fp);
    fp = NULL;
}
void seebook(Node L)
{
    char num[N];
    Node p;
    printf("-----------------------------------*图书查找系统*--------------------------------------------\n");
    printf("请输入查找的图书编号:>\n");
    scanf("%s", num);
    p = L->next;
    while (p && strcmp(p->date.num, num) != 0)
    {
        p = p->next;
    }
    if (p)
    {
        printf("*-----------------------*\n");
        printf("书名:%s\t编号:%s\t价格:%d", p->date.namebook, p->date.num, p->date.price);  //如果不是NULL,就输出节点信息
        printf("\n*-----------------------*\n");
    }
    else
    {
        printf("该图书信息还没有录入系统!\n");
    }
    printf("------------------------------------*图书查找系统欢迎您*---------------------------------------\n");
}
void editbook(Node L)
{
    char num[N];
    int input = 0;
    Node p;
    printf("-----------------------------------*图书修改系统*--------------------------------------------\n");
    printf("----------------------------\n");
    printf("|-------*1.图书编号*-------|\n");
    printf("|-------*2.图书名字*-------|\n");
    printf("|-------*3.图书价格*-------|\n");
    printf("----------------------------\n");
    printf("请输入查找的图书编号:>\n");
    scanf("%s", num);
    p = L->next;
    while (p && strcmp(p->date.num, num) != 0)
    {
        p = p->next;
    }
    if (p)
    {
        printf("请选择你要修改的图书内容>:\n");
        printf("*-------------------------*\n");
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            printf("-------*修改图书编号*-------\n");
            scanf("%s", p->date.num);
            break;
        case 2:
            printf("-------*修改图书名字*-------\n");
            scanf("%s", p->date.namebook);
            break;
        case 3:
            printf("-------*修改图书价格*-------\n");
            scanf("%d", &p->date.price);
            break;
        default:
            printf("*-------------------------*\n");
            printf("输入错误,重新操作!\n");
            break;
        }
    }
    else
    {
        printf("该图书信息还没有录入系统!\n");
    }
}
void quitbook(Node L)
{
    printf("*-------------------------#您已退出此系统,欢迎下次使用#-------------------------------*\n");
    exit(0);
}
int main()
{
    menu2();
    menu();
    Node L;
    L = inputbook();
    int input = 0;
    while (1)
    {
        menu();
        printf("\n*请输入你要进行的图书操作>:\n");
        scanf("%d", &input);
        switch (input)
        {
        case 1:assist(); break;
        case 2:printbook(L); break;
        case 3:chabook(L); break;
        case 4:freebook(L); break;
        case 5:fopenbook(L); break;
        case 6:quitbook(L); break;
        case 7:editbook(L); break;
        case 8:seebook(L); break;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/2301_79201049/article/details/134946937