基于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 4011 #define PASS_LEN 4012 #define USER_LEN 4013 #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_ERR24     };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);//调用普通管理员,这里的指针传全局的指针pmana30                 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;//读者的金额减少1091             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 }

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


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部