基于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 }
源代码我会上传的,这里是部分的代码希望初学者能从中学到知识
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
