基于C语言的图书管理系统,初学者的最佳选择

前言

这是我花了3天时间写的一个基于C语言的图书管理系统,里面包含了超级管理员,普通管理员,图书,读者4个模块。该管理系统使用了多文件的方式进行设计编写的,具有保存存储功能,也可以批量导入,批量导出,使用了动态内存分配,对于初学者入门,该文章是最好的选择了!!

下面展示一下流程图

在这里插入图片描述

展示一下我的文件分类

在这里插入图片描述

一些结构体的定义我都是放在一个peopleInfo.h中的
 #ifndef _PEOPLEINFO_H__
  2 #define _PEOPLEINFO_H__
  3 
  4 #include<stdio.h>
  5 #include<string.h>
  6 #include<stdlib.h>
  7 #define FILE_MNAME "mana.bin"
  8 #define FILE_RNAME "reader.bin"
  9 #define FILE_BNAME "book.bin"
 10 #define NAME_LEN 40
 11 #define PASS_LEN 40
 12 #define USER_LEN 40
 13 #define BOOK_LEN 150
enum SEX{MAN,WOMAN};
 16 enum RET_CODE{
 17     SUCCESS = 0,
 18     ARG_ERR,
 19     ALLOC_ERR,
 20     FAIL,
 21     OPEN_ERR,
 22     FILE_NOT_EXISTS,
 23     WRITE_ERR
 24     };
 25 typedef struct SuperInfo{//超级管理员
 26     int id;//工号
 27     char name[NAME_LEN];//名字
 28     int age;//年龄
 29     enum SEX sex;//性别 
 30 }Super;
 31 
 32 typedef struct ManaInfo{//普通管理员
 33     int id;//工号
 34     char name[NAME_LEN];//名字
 35     int age;//年龄
 36     enum SEX sex;//性别
 37     char user[USER_LEN];//用户名
 38     char pass[PASS_LEN];//密码
 39 }Mana;
 40 
 41 typedef struct BookInfo{//图书结构体
 42     int id;//书号
 43     char name[NAME_LEN];//书名
 44     char author[NAME_LEN];//作者
 45     double price;//价格
 46     int state;//状态,可借or不可借or被预约
 47     int lender;//借这本书的人
 48 }Book;
typedef struct ReaderInfo{//读者
 51     int id;//读者号
 52     char name[NAME_LEN];//名字
 53     int age;//年龄
 54     enum SEX sex;//性别
 55     double balance;//余额
 56     char borrowBook[10][BOOK_LEN];//所借的书
 57     char orderBook[10][BOOK_LEN];//预约书
 58     char user[USER_LEN];//用户名
 59     char pass[PASS_LEN];//密码
 60 }Reader;
 61 
 62 
 63 extern Mana *pmana;//记录普通管理员信息 需要申请动态内存
 64 extern size_t msize;//申请动态内存能够存储管理员信息的数量
 65 extern size_t mcnt;//当前动态内存中管理员信息数量
 66 extern int makeId;//自动生成管理员工号
 67 
 68 extern Book *pbook;//记录图书信息 要申请动态内存
 69 extern size_t bsize;//申请动态内存能够存储图书信息的数量
 70 extern size_t bcnt;//当前动态内存中图书信息数量
 71 extern int bookId;//自动生成书号
 72 
 73 extern Reader *preader;//记录读者信息 需要申请动态内存
 74 extern size_t rsize;//申请动态内存能够存储读者信息的数量
 75 extern size_t rcnt;//当前动态内存中读者信息数量
 76 extern int readerId;//自动生成读者号
 77 
 78 
 79 #endif //_PEOPLEINFO_H__

主界面的3个登录界面

多文件的好处就是可以使代码更好的分类,做项目的时候它不可能把所有的东西都写在一个文件中,我一个view.c文件中要编写功能代码,那么我要在view.h文件中去声明好这些函数,做好一一对应,那么在调用的时候只要调用view.h文件就行了

  1 #include "view.h"
  2 #include "oper.h"
  3 #include "viewMana.h"
  4 #include "viewSuper.h"
  5 #include "viewReader.h"
  6 
  7 void showPeopleType(){//第一个界面,显示人员的类型
  8     printf("指针图书信息管理\n");
  9     printf("1 超级管理员\n");
 10     printf("2 普通管理员\n");
 11     printf("3 普通会员\n");
 12     printf("0 退出\n");
 13 }
 14 
 15 void run(){// 
 16         showPeopleType();
 17         int oper = 0;
 18         scanf("%d",&oper);
 19         switch(oper){
 20             case 0:
 21                 manaSave(FILE_MNAME);
 22                 readerSave(FILE_RNAME);
 23                 bookSave(FILE_BNAME);
 24                 exit(0);
 25             case 1:
 26                 superLogin();//调用超级管理员
 27                 break;
 28             case 2:
 29                 manaLogin(pmana);//调用普通管理员,这里的指针传全局的指针pmana
 30                 break;
 31             case 3:
 32                 readerLogin(preader);
 33                 break;
 34         }
 35 }

在这里插入图片描述
在这里插入图片描述
增删改查的功能在oper.c中,这里是他们函数的逻辑功能实现代码

  1 #include "oper.h"
  2 
  3 int addMana(Mana *pm){//添加一个管理员
  4     if(pm == NULL){//指针为空
  5         return ARG_ERR;
  6     }
  7     if(pmana == NULL){//第一次申请
  8         pmana = malloc(sizeof(Mana)*msize);
  9     }
 10     if(pmana != NULL && msize == mcnt){//满了
 11         msize *= 2;//扩容
 12         pmana = realloc(pmana,sizeof(Mana)*msize);
 13     }
 14     if(pmana == NULL){//如果申请动态内存失败了
 15         return ALLOC_ERR;
 16     }
 17     pmana[mcnt] = *pm;//把该管理员放进去
 18     ++mcnt;
 19     return SUCCESS;
 20 }
 21 
 22 int delMana(int id){//删除管理员
 23     int i;
 24     for(i = 0; i < mcnt; i++){
 25         if(pmana[i].id == id){
 26             pmana[i] = pmana[mcnt-1];
 27             mcnt--;
 28             return SUCCESS;
 29         }
 30     }
 31     return;
 32 }
Mana* findMana(int id){//查找管理员
 35     int i;
 36     for(i = 0; i < mcnt; i++){
 37         if(pmana[i].id == id){
 38             return &pmana[i];
 39         }
 40     }
 41     return NULL;
 42 }
 43 
 44 int addBook(Book *pb){//增加一本书
 45     if(pb == NULL){//指针为空
 46         return ARG_ERR;
 47     }
 48     if(pbook == NULL){//第一次申请
 49         pbook = malloc(sizeof(Book)*bsize);
 50     }
 51     if(pbook != NULL && bsize == bcnt){//满了
 52         bsize *= 2;//扩容
 53         pbook = realloc(pbook,sizeof(Book)*bsize);
 54     }
 55     if(pbook == NULL){//如果申请动态内存失败了
 56         return ALLOC_ERR;
 57     }
 58     pbook[bcnt] = *pb;//把该书放进去
 59     ++bcnt;
 60     return SUCCESS;
 61 }
 63 int delBook(int id){//删除一本书
 64     int i;
 65     for(i = 0; i < bcnt; i++){
 66         if(pbook[i].id == id){
 67             pbook[i] = pbook[bcnt-1];
 68             --bcnt;
 69             return SUCCESS;
 70         }
 71     }
 72     return;
 73 }
 74 
 75 Book *findBook(int id){//查找一本书
 76     int i;
 77     for(i = 0; i < bcnt; i++){
 78         if(pbook[i].id == id){
 79             return &pbook[i];
 80         }
 81     }
 82     return NULL;
 83 }
 85 int addReader(Reader *pr){//增加一个读者    
 86     if(pr == NULL){
 87         return ARG_ERR;
 88     }
 89     if(preader == NULL){
 90         preader = malloc(sizeof(Reader)*rsize);
 91     }
 92     if(pr != NULL && rcnt == rsize){
 93         rsize *= 2;
 94         preader = realloc(preader,sizeof(Reader)*rsize);
 95     }
 96     if(preader == NULL){//申请失败
 97         return ALLOC_ERR;
 98     }
 99     preader[rcnt] = *pr;
100     ++rcnt;
101     return SUCCESS;
102 }
103 
104 int delReader(int id){
105     int i;
106     for(i = 0; i < rcnt; i++){
107         if(preader[i].id == id){
108             preader[i] = preader[rcnt-1];
109             --rcnt;
110             return SUCCESS;
111         }
112     }
113     return;
114 }
116 Reader *findReader(int id){
117     int i;
118     for(i = 0; i < rcnt; i++){
119         if(preader[i].id == id){
120             return &preader[i];
121         }
122     }
123     return NULL;
124 }

以图书模块的增删改为例

  1 #include "viewMana.h"
  2 #include "oper.h"
  3 
  4 void showBook(Book *pb){//显示图书
  5     printf("书号:%d\n",pb->id);
  6     printf("书名:%s\n",pb->name);
  7     printf("作者:%s\n",pb->author);
  8     printf("价格:%.2lf\n",pb->price);
  9     printf("状态:%s\n",pb->state == 0 ? "可借":(pb->state == 1 ?"借阅":(pb->state==2?"预约":"借阅预约")));//0 空闲可借 1 被借走  2 被预约 3借阅中,被>    预约
 10     printf("借阅者:%d\n",pb->lender);
 11 }
 12 
 13 void addBooks(){//增加图书
 14     Book b = {};
 15     b.id = bookId++;
 16     printf("增加图书\n");
 17     printf("请输入书名\n");
 18     scanf("%s",b.name);
 19     printf("请输入作者\n");
 20     scanf("%s",b.author);
 21     printf("请输入价格\n");
 22     scanf("%lf",&b.price);
 23     printf("请输入状态 0-可借 1-借阅 2-预约 3-借阅预约\n");
 24     scanf("%d",&b.state);
 25     //printf("借这本书的人\n");
 26     //scanf("%d",&b.lender);
 27     addBook(&b);
 28     showBook(&b);
 29 }
 31 void delBooks(){//删除图书
 32     printf("请输入要删除的书号\n");
 33     int id = 0;
 34     scanf("%d",&id);
 35     if(delBook(id) == SUCCESS){
 36         printf("删除成功\n");
 37     }else{
 38         printf("没有该书\n");
 39     }
 40 
 41 }
 42 
 43 void altBooks(){//修改图书
 44     printf("请输入要修改的书号\n");
 45     int id;
 46     scanf("%d",&id);
 47     Book *pb = findBook(id);
 48     if(pb == NULL){
 49         printf("没有该书\n");
 50         return;
 51     }
 52     showBook(pb);
 53     printf("请输入书名\n");
 54     scanf("%s",pb->name);
 55     printf("请输入作者\n");
 56     scanf("%s",pb->author);
 57     printf("请输入价格\n");
 58     scanf("%lf",&pb->price);
 59     printf("借阅情况 0-可借 1-借阅 2-预约 3-借阅预约\n");
 60     scanf("%d",&pb->state);
 61 }
 63 void findBooks(){//查找图书
 64     printf("请输入要查找的书号\n");
 65     int id = 0;
 66     scanf("%d",&id);
 67     Book *pb = findBook(id);
 68     if(pb == NULL){
 69         printf("没有这本书\n");
 70         return;
 71     }
 72     showBook(pb);
 73 }
 74 
 75 void listBooks(){//列出图书
 76     if(bcnt == 0){
 77         return;
 78     }
 79     printf("-----------------------------------------------------------------------\n");
 80     printf("书号\t书名\t作者\t价格\t借阅情况\t借阅者id\n");
 81     int i;
 82     for(i = 0; i < bcnt; i++){
 83     printf("%d\t%s\t%s\t%.2lf\t%s\t\t%d\n",pbook[i].id,pbook[i].name,pbook[i].author,pbook[i].price,pbook[i].state==0?"可借":(pbook[i].state==1?"借阅"    :(pbook[i].state==2?"预约":"借阅预约")),pbook[i].lender);
 84     }
 85     printf("-----------------------------------------------------------------------\n");
 86 }

文件的导入导出同样以图书为例

 88 void importBooks(){
 89     char path[NAME_LEN];
 90     Book im = {};
 91     int ret;
 92     printf("请输入你要导入的源文件\n");
 93     scanf("%s",path);
 94     FILE *frp = fopen(path,"r");
 95     if(frp != NULL){
 96         while(1){
 97             char imState[NAME_LEN];
 98             ret = fscanf(frp,"%d%s%s%lf%s%d",&im.id,im.name,im.author,&im.price,imState,&im.lender);
 99             if(ret > 0){
100                 if(strcmp(imState,"可借") == 0){
101                     im.state = 0;
102                 }else if(strcmp(imState,"借阅") == 0){
103                     im.state = 1;
104                 }else if(strcmp(imState,"预约") == 0){
105                     im.state = 2;
106                 }else{
107                     im.state = 3;
108                 }
109                 addBook(&im);
110             }else{
111                 printf("导入完成\n");
112                 break;
113             }
114         }
115     }
116 
117 }
118 void exportBooks(){
119     char path[NAME_LEN];
120     printf("请输入你要导出的文件名\n");
121     scanf("%s",path);
122     FILE *fwp = fopen(path,"w");
123     int i;
124     if(fwp != NULL){
125         for(i = 0; i < bcnt; i++){
126             fprintf(fwp,"%d\t%s\t%s\t%.2lf\t%s\t%d\n",pbook[i].id,pbook[i].name,pbook[i].author,pbook[i].price,pbook[i].state==0?"可借":(pbook[i].stat    e==1?"借阅":(pbook[i].state==2?"预约":"借阅预约")),pbook[i].lender);
127         }
128     }
129     fclose(fwp);
130 }

借书还书部分的设计还不够完善,只写了借一本还一本预约也只能一本,定义结构体时候可以把变量定义为数组,后序 完善了会补充

  1 #include "viewReader.h"
  2 #include "oper.h"
  3 #include<assert.h>
  4 
  5 
  6 void readerAdmin(){//读者目录
  7     printf("指针图书信息管理系统 -- 读者\n");
  8     printf("1 查找图书(借阅.还书.预约)\n");//模糊查询 借阅 还书 预约图书
  9     printf("2 充值余额\n");
 10     printf("3 修改密码\n");
 11     printf("4 返回\n");
 12     printf("0 退出\n");
 13 }
 14 
 15 void fuzzy(const char *dady,const char *baby){
 16     assert(dady!=NULL&& baby!=NULL );
 17     int i=0;
 18     size_t len = strlen(baby);
 19     while(dady[i] != '\0'){
 20         if(dady[i] == baby[0]){
 21             if(strncmp(baby,dady+i,len)==0){
 22                 printf("%s   ",dady);
 23             }
 24         }
 25         i++;
 26     }
 27 } 29 Book *fuzzyBooks(Reader *pr){   //查找书籍
 30     if(pbook == NULL){
 31         printf("the list is empty!\n");
 32         return pbook;
 33     }
 34     Book *pb = pbook;
 35     char seekName[NAME_LEN];
 36     printf("请输入您要查找的书籍名(模糊匹配):");
 37     scanf("%*c");
 38     scanf("%[^\n]",seekName);
 39     int i=0;
 40     int len = strlen(seekName);
 41     printf("您可能想要查找的书籍如下:\n");
 42     for(i=0;i<bcnt;i++){
 43         fuzzy(pb[i].name,seekName);
 44     }
 45     printf("请您选择输入具体书名:");
 46     scanf("%*c");
 47     scanf("%[^\n]",seekName);
 48     i=0;
 49     while(strcmp(pb->name,seekName)!=0 && i<bcnt){
 50         pb++;
 51         i++;
 52     }
 53     if(strcmp(pb->name,seekName) == 0){
 54         printf("编号为%d 的书籍的信息如下:\n",pb->id);
 55         printf("书号:%d\t书名:%s\t作者:%s\t价格:%.2lf\t状态:%s\t借阅者%d\n",pb->id,pb->name,pb->author,pb->price,pb->state==0?"可借":(pb->state==1?"借
    阅":(pb->state ==2?"预约":"借阅预约")),pb->lender);
 56         printf("请操作:1-借阅书籍 2-预约书籍 3-归还书籍 4-返回");
 57         int opt;
 58         scanf("%d",&opt);
 59         switch(opt){
 60             case 1:
 61             borrowBooks(pb,pr);
 62             break;
 63             case 2:
 64             appBooks(pb,pr);
 65             break;
 66             case 3:
 67             returnBooks(pb,pr);
 68             case 4:
 69             return pbook;
 70             break;
 71             default:
 72             printf("illegal input!\n");
 73             break;
 74         }
 75     }else{
 76         printf("查无此书籍!\n");
 77     }
 78     return pbook;
 79 }
 80 void borrowBooks(Book *pb,Reader *pr){
 81     if(pb->state == 1){//被借走
 82         printf("这本书被借走了\n");
 83         return;
 84     }else if(pb->state == 2){//被预约
 85         if(strcmp(pr->orderBook[0],pb->name) == 0 && pb->lender == 0){//1预约者与被预约的书一样才能借2这本书别人已经还了
 86             printf("成功借走这本书\n");
 87             pb->state = 1;//状态变为借走
 88             pb->lender = pr->id;//把读者的id赋值给书的借阅者
 89             strcpy(pr->borrowBook[0],pb->name);//把书名赋值给读者所借的书
 90             pr->balance -= 10;//读者的金额减少10
 91             strcpy(pr->orderBook[0],NULL);
 92         }else{
 93             printf("这本书被预约了,不能借走\n");
 94         }   
 95     }else{  
 96         printf("成功借走\n");
 97         pb->state = 1;//状态变成借走
 98         pb->lender = pr->id;//把读者的id赋值给书的借阅者
 99         strcpy(pr->borrowBook[0],pb->name);//把书名赋值给读者所借的书
100         pr->balance -= 10;//读者的金额减少10
101         return;
102     }
103 }
104 
105 void returnBooks(Book *pb,Reader *pr){
106     printf("请输入要归还的书号\n");
107     int id = 0;
108     scanf("%d",&id);
109     int i = 0;
110     while(i < bcnt && pb->id != id){
111         i++;
112         pb++;
113     }
114     if(pb->id == id){
115         if(strcmp(pb->name,pr->borrowBook[0]) == 0){//借的书和书名一样
116                 pb->state = 0;
117                 pb->lender = 0;//书的使用者变为空
118                 strcmp(pr->borrowBook[0],"NULL");//读者所借的书变为空
119                 printf("还书成功\n");
120         }else{
121             printf("这本书你没有借,无法归还\n");
122         }
123     }else{
124         printf("没有这本书\n");
125     }
126 }
127 void appBooks(Book *pb,Reader *pr){//预约书籍
128     if(strcmp(pr->orderBook[0],"NULL") != 0){
129         printf("你已经有预约的书了,预约失败\n");
130         return;
131     }
132     if(pb->state == 0){//可借
133         pb->state = 2;
134         strcpy(pr->orderBook[0],pb->name);
135         pr->balance -= 2;
136         printf("你成功预约了这本书\n");
137         return;
138     }else if(pb->state == 1){//被借走
139         pb->state = 3;//被借走的书,被预约了
140         pr->balance -= 2;
141         printf("你成功预约了这本书,等别人还了你就能借啦\n");
142         return;
143     }else{//被预约了
144         printf("这本书别人预约了,预约失败\n");
145         return;
146     }
147 }
148 
149 void balanceAdd(Reader *pr){
150     double money = 0;
151     printf("你当前的余额为%.2lf\n",pr->balance);
152     printf("请输入要充值的金额\n");
153     scanf("%lf",&money);
154     pr->balance += money;
155     printf("你充值后的余额为%.2lf\n",pr->balance);
156 }
157 
158 void changePass(Reader *pr){
159     printf("请输入原来的密码\n");
160     char oldPass[NAME_LEN];
161     scanf("%s",oldPass);
162     if(strcmp(pr->pass,oldPass) == 0){
163         printf("请输入新密码");
164         scanf("%s",pr->pass);
165     }else{
166         printf("你输入的旧密码有错\n");
167     }
168 }

登录差点给忘了,看看读者登录

170 void readerLogin(Reader *pr){//读者登陆
171     size_t i,j;
172     char in_user[20];
173     char in_pass[20];
174     int flag = 0;
175     printf("你有3次输入的机会\n");
176     for(j = 0; j < 3; j++){
177         printf("请输入用户名\n");
178         scanf("%s",in_user);
179         for(i = 0; i < rcnt; i++){
180             if(strcmp(pr[i].user,in_user) == 0){
181                 printf("请输入密码\n");
182                 scanf("%s",in_pass);
183                 if(strcmp(pr[i].pass,in_pass) == 0){
184                     flag = 1;
185                     break;
186                 }
187             }
188         }
189         if(flag == 1){
190             break;
191         }
192     }
193     if(j < 3){
194         printf("登陆成功\n");
195         while(1){
196             readerAdmin();
197             int opt = 0;
198             scanf("%d",&opt);
199             switch(opt){
200                 case 1:
201                 fuzzyBooks(pr+i);//模糊查询
202                 break;
203                 case 2:
204                 balanceAdd(pr+i);//余额充值
205                 break;
206                 case 3:
207                 changePass(pr+i);//修改密码
208                 break;
209                 case 4:
210                 run();//返回
211                 case 0:
212                 manaSave(FILE_MNAME);
213                 readerSave(FILE_RNAME);
214                 bookSave(FILE_BNAME);
215                 exit(0);
216                 break;
217             }
218         }
219     }else{
220         printf("登陆失败\n");
221         run();
222     }
223 }

源代码我会上传的,这里是部分的代码希望初学者能从中学到知识

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值