信息时代的到来,人类逐渐走向信息化,图书馆保存这大量信息资源,需要一个信息库对图书信息进行保存,图书馆管理系统应此而生。
该图书馆管理系统使用vs2019编译器c语言进行编写,首先对可能会使用到的c语言知识进行学习,再开始对程序的编写。
程序编写中首先理清程序框架,以程序框图的方法画出整个程序各个功能的连接与关系。然后实现界面设计,最终补充程序的基础功能和高级功能,最后对程序进行debug和优化程序逻辑,最终对程序进行最终测试,优化程序,最终完成图书馆管理系统。
目前程序已实现众多功能,面向管理员:非明文登录,图书信息登录,图书信息修改,用户信息管理,浏览借阅信息,浏览用户信息。面向用户:用户的注册和登录,查看图书信息,浏览目前已借阅书籍,查看归还时间,借阅和归还书籍。
程序的亮点,目前有动态展示界面,以及保持界面位置恒定不变,对管理员账号进行了重点保护。
本程序可以放内置bgm,不过需要easyx的支持,且将文件名改为k(拓展名为MP3)并与程序放在同一目录。
也可以使用软件的欢迎窗口,同样是easyx的功能,文件名为t(默认格式jfif,若要使用其他格式图片,请修改代码中的拓展名)。
动态展示界面需要创建文件名为
1.txt(展示登录与注册动态界面)
用户.txt(展示用户操作动态界面)
管理员.txt(展示管理员操作动态界面)
并在里面写入你要展示的界面即可。
话不多说,下面展示代码
#define _CRT_SECURE_NO_WARNINGS 1 #include#include #include #include //图形库头文件 #include //多媒体设备接口文件 #include //调用sleep函数 #include #pragma comment(lib,"winmm.lib") #define MAX 80 #include #pragma warning(disable:4996) / char null[20] = {""}; char adminlogin[20];//用于接受当前登录用户的用户名 struct joints* result_; //以下是图形库内容 void PlayBGM() { //1打开音乐 mciSendString("open k.mp3", 0, 0, 0); //2播放音乐 mciSendString("play k.mp3", 0, 0, 0); //3关闭音乐 // Sleep(3000); //mciSendString("close k.mp3", 0, 0, 0); } void playbgmandpicture(void) { initgraph(800, 517,SHOWCONSOLE); IMAGE img; loadimage(&img, "t.jfif"); putimage(0, 0, &img); //setbkcolor(YELLOW);//设置背景色,考虑不使用暂时储存 //cleardevice();//清空画板和上面配套使用 PlayBGM(); } struct admin { char username[20];//用户账号名 char pin[20];//用户密码 char name[20];//用户借阅书的名字 int Num;//用户借书数量 time_t start;//借书时间 }; struct joints { struct admin data; struct joints* next; }; struct joints* _list = NULL; //制作表头 struct joints* createHeadadmin_() { struct joints* headNode = (struct joints*)malloc(sizeof(struct joints));//动态内存申请 headNode->next = NULL; return headNode; } //制作节点 struct joints* createNode_(struct admin data) { struct joints* newNode = (struct joints*)malloc(sizeof(struct joints)); newNode->data = data; newNode->next = NULL; return newNode; } //表头法插入 void insertNodeByHead_(struct joints* headNode, struct admin data) { struct joints* newNode = createNode_(data); newNode->next = headNode->next; headNode->next = newNode; } //文件存储操作 void saveInfoTofile_(const char* filename, struct joints* headNode) { FILE* fp = fopen(filename, "w"); struct joints* pMove = headNode->next; while (pMove != NULL) { fprintf(fp, "%st%st%st%dt%dn", pMove->data.username, pMove->data.pin, pMove->data.name, pMove->data.Num,pMove->data.start); pMove = pMove->next; } fclose(fp); } //文件读操作 void readInfoFromFile_(const char* filename, struct joints* headNode) { FILE* fp = fopen(filename, "r"); if (fp == NULL)//如果文件不存在就创建一个文件 { fp = fopen(filename, "w+"); } struct admin tempData; while (fscanf(fp, "%st%st%st%dt%dn", tempData.username, tempData.pin, tempData.name, &tempData.Num,&tempData.start) != EOF)//EOF是文件结束标记,当没有读到文件结束标记时进行链表插入 { insertNodeByHead_(_list, tempData); } fclose(fp); } //查找用户名 struct joints* searchByusername(struct joints* headNode, char* temp) { struct joints* posNode = headNode->next; while (posNode != NULL && strcmp(posNode->data.username, temp)) { posNode = posNode->next; } return posNode; } //查找密码 struct joints* searchBypin(struct joints* headNode, char* temp) { struct joints* posNode = headNode->next; while (posNode != NULL && strcmp(posNode->data.pin, temp)) { posNode = posNode->next; } return posNode; } //查找已经借阅书籍 struct joints* searchByname(struct joints* headNode, char* temp) { struct joints* posNode = headNode->next; while (posNode != NULL && strcmp(posNode->data.pin, temp)) { posNode = posNode->next; } return posNode; } //指定删除用户 void shanchu_(struct joints* headNode, char* adminName) { struct joints* posLeftNode = headNode;//删除节点左边 struct joints* posNode = headNode->next;//删除节点右边 while (posNode != NULL && strcmp(posNode->data.username, adminName)) { posLeftNode = posNode; posNode = posLeftNode->next; } //讨论查找的结果 if (posNode == NULL) { printf("未查询到此账号名,请重试!n"); return; } else { printf("成功删除!!!n"); posLeftNode->next = posNode->next; free(posNode); posNode = NULL; return; } } void printAdminList(struct joints* headNode) { struct joints* pMove = headNode->next; printf("tt 用户名ttt已借书ttt借书数量tt 剩余还书时间(小时)n"); while (pMove) { time_t end = time(NULL); int borrowingtime = (end - pMove->data.start);//计算借阅时间所用目前时间 int timeleft = (1209600 - borrowingtime) / 3600;//计算借书剩余时间(小时) if (pMove->data.Num == 0) { timeleft = 0; } printf("%25s%27s%25d%25dn", pMove->data.username, pMove->data.name, pMove->data.Num, timeleft); pMove = pMove->next; } } // // // // // // struct bookInfo { float price;//书的价格 char name[20];//书的名字 int num;//书的数量 }; struct Node { struct bookInfo data; struct Node* next; }; struct Node* list = NULL; //制作表头 struct Node* createHeadadmin() { struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));//动态内存申请 headNode->next = NULL; return headNode; } //制作节点 struct Node* createNode(struct bookInfo data) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = data; newNode->next = NULL; return newNode; } //表头法插入 void insertNodeByHead(struct Node* headNode, struct bookInfo data) { struct Node* newNode = createNode(data); newNode->next = headNode->next; headNode->next = newNode; } //打印链表 void printList(struct Node* headNode) { struct Node* pMove = headNode->next; printf("书名ttt价格ttt数量n"); while (pMove) { if(strlen(pMove->data.name) < 7) printf(" %sttt%.1fttt%dn", pMove->data.name, pMove->data.price, pMove->data.num); else { printf(" %stt%.1fttt%dn", pMove->data.name, pMove->data.price, pMove->data.num); } pMove = pMove->next; } } //指定删除 void sort(struct Node* headNode, char *bookName) { struct Node* posLeftNode = headNode;//删除节点左边 struct Node* posNode = headNode->next;//删除节点右边 while (posNode != NULL && strcmp(posNode->data.name, bookName))//注意该行有问题 { posLeftNode = posNode; posNode = posLeftNode->next; } //讨论查找的结果 if (posNode == NULL) { printf("未查询到此书籍,请输入正确的书名!"); return; } else { printf("成功删除!!!"); posLeftNode->next = posNode->next; free(posNode); posNode = NULL; return; } } //查找书籍 struct Node* searchByName(struct Node* headNode, char* bookName) { struct Node* posNode = headNode->next; while (posNode != NULL && strcmp(posNode->data.name, bookName)) { posNode = posNode->next; } return posNode; } //模糊搜索 int mohusearchByName(struct Node* headNode, char* bookName) { struct Node* posNode = headNode->next; int i = 0; printf("书名ttt价格ttt数量n"); while (posNode != NULL ) { if (strstr(posNode->data.name, bookName)) { if (strlen(posNode->data.name) < 7) printf(" %sttt%.1fttt%dn", posNode->data.name, posNode->data.price, posNode->data.num); else { printf(" %stt%.1fttt%dn", posNode->data.name, posNode ->data.price, posNode->data.num); } posNode = posNode->next; i++; } else { posNode = posNode->next; } } return i; } void makemenu0() { FILE* p; char c; int b; b = 10; char a[] = { "管理员.txt" }; p = fopen(a, "r"); if (p != NULL) { for (; (c = fgetc(p)) != EOF;) { printf("%c", c); Sleep(b); } fclose(p); } } void makemenu1() { FILE* p; char c; int b; b = 10; char a[] = { "用户.txt" }; p = fopen(a, "r"); if (p != NULL) { for ( ;(c = fgetc(p)) != EOF;) { printf("%c", c); Sleep(b); } fclose(p); } } void menu() { FILE* p; char c; int b; b = 10; char a[] = { "1.txt" }; p = fopen(a, "r"); if (p != NULL) { for (; (c = fgetc(p)) != EOF;) { printf("%c", c); Sleep(b); } fclose(p); } } //管理员后续界面 void makemenu() { printf("**************************************************n"); printf("* 图书管理系统测试版 *n"); printf("*t1.登记书籍 *n"); printf("*t2.浏览书籍 *n"); printf("*t3.排序书籍 *n"); printf("*t4.删除书籍 *n"); printf("*t5.查找书籍 *n"); printf("*t6.模糊搜索 *n"); printf("*t7.用户信息 *n"); printf("*t8.用户删除 *n"); printf("*t9.退出系统 *n"); printf("**************************************************n"); printf("请首先输入数字1到9。n"); } //用户后续界面 void makemenuj() { time_t timer; struct tm* Now; time(&timer); Now = localtime(&timer);//目前时间 time_t end = time(NULL); struct joints* result_; result_ = searchByusername(_list, adminlogin); int borrowingtime = (end - result_->data.start);//计算借阅时间所用目前时间 int timeleft = (1209600 - borrowingtime)/3600;//计算借书剩余时间(小时) printf("**************************************************n"); printf("* 图书管理系统测试版 *n"); printf("*t1.浏览书籍 *n"); printf("*t2.借阅书籍 *n"); printf("*t3.归还书籍 *n"); printf("*t4.排序书籍 *n"); printf("*t5.查找书籍 *n"); printf("*t6.模糊搜索 *n"); printf("*t7.退出系统 *n"); printf("**************************************************n"); printf("请首先输入数字1到7。n"); if (result_->data.Num > 0) { printf("nnntt目前已借阅书籍为%sn", result_->data.name); printf("nnntt目前已借阅书籍数量为%dn", result_->data.Num); printf("nnntt当前的本地时间和日期:%sn", asctime(Now)); printf("nnntt请在%d小时内归还书籍n", timeleft);//129600秒为14天,计算14天与借书时间的差 } else { printf("nnntt当前的本地时间和日期:%sn", asctime(Now)); printf("nnntt您暂未借任何书籍!n"); } } //文件存储操作 void saveInfoTofile(const char* filename, struct Node* headNode) { FILE* fp = fopen(filename, "w"); struct Node* pMove = headNode -> next; while (pMove != NULL) { fprintf(fp, "%st%ft%dn", pMove->data.name, pMove->data.price, pMove->data.num); pMove = pMove->next; } fclose(fp); } //文件读操作 void readInfoFromFile(const char* filename, struct Node* headNode) { FILE* fp = fopen(filename, "r"); if (fp == NULL)//如果文件不存在就创建一个文件 { fp = fopen(filename, "w+"); } struct bookInfo tempData; while (fscanf(fp, "%st%ft%dn", tempData.name, &tempData.price, &tempData.num) != EOF)//EOF是文件结束标记,当没有读到文件结束标记时进行链表插入 { insertNodeByHead(list, tempData); } fclose(fp); } //排序 void sort(struct Node* headNode) { for (struct Node* p = headNode->next; p != NULL; p = p->next) { for (struct Node* q = headNode->next; q->next != NULL; q = q->next) { if (q->data.price > q->next->data.price) { struct bookInfo tempData = q->data; q->data = q->next->data; q->next->data = tempData; } } } printList(headNode); } //管理员操作界面 void keydown0() { int key = 0; struct bookInfo tempBook;//创建一个临时变量储存书籍信息 struct admin temp;//创建一个临时账户 struct Node* result; int i ; scanf("%d", &key); system("cls"); switch (key) { case 1: { char str1[100]; gets_s(str1); printf("t《登记书籍》n"); printf("输入书籍的信息(书名,价格,数量)n温馨提示:价格请控制在200以内n"); scanf("%s%f%d", tempBook.name, &tempBook.price, &tempBook.num); //下方代码检验是否已有书籍 result = searchByName(list, tempBook.name); if (result != NULL) { printf("该书籍已经登录,如需修改书籍信息,请先删除书籍再登录!n"); } else { int a = tempBook.price; int b = tempBook.num; if ((a >= 200 || a <= 0) || (b >= 200 || b <= 0)) { printf("输入格式错误"); } else { insertNodeByHead(list, tempBook); saveInfoTofile("bookinfo.txt", list); printf("登记成功n"); } } } char str9[100]; gets_s(str9); break; case 2: char str2[100]; gets_s(str2); printf("t《浏览书籍》n"); printList(list); break; case 3: char str5[100]; gets_s(str5); printf("t《排序书籍》n"); sort(list); break; case 4: char str6[100]; gets_s(str6); printf("t《删除书籍》n"); printf("请输入删除书籍的名字"); scanf("%s", tempBook.name); sort(list, tempBook.name);// 删除链表中内容 saveInfoTofile("bookinfo.txt", list);//存储文件 break; case 5: char str7[100]; gets_s(str7); printf("t《查找书籍》n"); printf("请输入你要查询的书名"); scanf("%s", tempBook.name); result = searchByName(list, tempBook.name); if (result == NULL) { printf("未找到相关书籍!n"); } else { if (strlen(result->data.name) < 7) printf(" %sttt%.1fttt%dn", result->data.name, result->data.price, result->data.num); else { printf(" %stt%.1fttt%dn", result->data.name, result->data.price, result->data.num); } char str8[100]; gets_s(str8); } break; case 6://模糊搜索 char str62[100]; gets_s(str62); printf("t《模糊搜索》n"); printf("请输入你要查询的书名的关键字"); scanf("%s", tempBook.name); i = mohusearchByName(list, tempBook.name); if (i == 0) { printf("未找到相关书籍!n"); } char str100[100]; gets_s(str100); break; case 7://用户信息查询 char str29[100]; gets_s(str29); printf("ttttt《查询用户信息》n"); printAdminList(_list); break; case 8://用户删除 printf("《用户删除》n"); char str16[100]; gets_s(str16); printf("请输入删除用户的账号名n"); scanf("%s", temp.name); shanchu_(_list, temp.name);// 删除链表中内容 saveInfoTofile_("admin.txt", _list);//存储文件 char str101[100]; gets_s(str101); break; case 9://曾是case0,但case0会触发default的条件所以换成case10 printf("t《退出》n"); printf("退出成功!"); system("pause"); exit(0); //退出程序 break; default: printf("t《error》n"); char str[100]; gets_s (str); break; } } //用户操作界面 void keydown1() { int key = 0; struct bookInfo tempBook;//创建一个临时变量储存书籍信息 struct Node* result; struct joints* result_; result_ = searchByusername(_list, adminlogin); scanf("%d", &key); int i; system("cls"); switch (key) { case 1: char str2[100]; gets_s(str2); printf("t《浏览书籍》n"); printList(list); break; case 2: char str3[100]; gets_s(str3); printf("t《借阅书籍》n"); system("cls"); printList(list); printf("请输入借阅的书名:n"); scanf("%s", tempBook.name); result = searchByName(list, tempBook.name); if (result == NULL) { printf("没有该书籍,无法借阅n"); } else { if (result->data.num > 0) { if (result_->data.Num == 2) { printf("您已借俩本书,请至少归还一本书后再借书!n"); } else { if (strstr(result_->data.name, tempBook.name) != NULL) { printf("您已借阅该书籍,请不要重复借阅该书!n"); break; } result->data.num--; printf("借阅成功n"); result_->data.Num++; strcat(result_->data.name, tempBook.name); result_->data.start = time(NULL); } } else { printf("当前书籍已借完!n请稍候几天再借阅。n"); } } saveInfoTofile_("admin.txt", _list); saveInfoTofile("bookinfo.txt", list); break; case 3: char str4[100]; gets_s(str4); printf("t《归还书籍》n"); printf("请输入您要归还的书籍!n"); scanf("%s", tempBook.name); result = searchByName(list, tempBook.name); if (result == NULL) { printf("没有该书籍,可能不是该图书馆书籍。n"); } else { result->data.num++; result_->data.Num--; char* p; char temp[85]; while ((p = strstr(result_->data.name, tempBook.name)) != NULL) { *p = ' '; strcpy(temp, p + strlen(tempBook.name)); strcat(result_->data.name, temp); } saveInfoTofile_("admin.txt", _list); saveInfoTofile("bookinfo.txt", list); printf("归还成功n"); } break; case 4: char str5[100]; gets_s(str5); printf("t《排序书籍》n"); sort(list); break; case 5: char str7[100]; gets_s(str7); printf("t《查找书籍》n"); printf("请输入你要查询的书名"); scanf("%s", tempBook.name); result = searchByName(list, tempBook.name); if (result == NULL) { printf("未找到相关书籍!n"); } else { if(strlen(result->data.name) < 7) printf(" %sttt%.1fttt%dn", result->data.name, result->data.price, result->data.num); else { printf(" %stt%.1fttt%dn", result->data.name, result->data.price, result->data.num); } char str8[100]; gets_s(str8); } break; case 6://模糊搜索 printf("t《模糊搜索》n"); printf("请输入你要查询的书名的关键字"); scanf("%s", tempBook.name); i = mohusearchByName(list, tempBook.name); if (i == 0) { printf("未找到相关书籍!n"); } char str100[100]; gets_s(str100); break; case 7://曾是case0,但case0会触发default的条件所以换成case7 printf("t《退出》n"); printf("退出成功!"); system("pause"); exit(0); //退出程序 break; default: printf("t《error》n"); char str[100]; gets_s(str); break; } } //注册账号 int registers() { struct admin temp;//创建一个临时变量储存注册账号 struct joints* result; char password1[20]; char password2[20]; printf("t《注册账号》n"); printf("请输入账号名n"); scanf("%s", temp.username); //下方代码检验是否已有账号 result = searchByusername(_list, temp.username); if (result != NULL) { printf("该账号已经注册,请使用其他账号名注册n"); system("pause"); return 0; } printf("请输入您的密码n"); scanf("%s", password1); printf("请再次输入您的密码n"); scanf("%s", password2); if(strcmp(password1, password2) == 0) { strcpy(temp.pin ,password1); strcpy(temp.name, null); temp.Num = 0; temp.start = 0; insertNodeByHead_(_list, temp); saveInfoTofile_("admin.txt", _list); printf("账号注册成功,您的用户名是%sn",temp.username); printf("您的密码是%sn", password1); } else { printf(" 俩次密码不一致,请重新注册n"); return 0; } char str9[100]; gets_s(str9); return 0; } //用户账号验证 int adminyanzheng() { char tempusername[20]; char temppin[20]; printf("请输入您的账号名n"); scanf("%s", tempusername); if(searchByusername(_list, tempusername) == NULL) { system("cls"); printf("您输入的账号名错误!n"); system("pause"); return 0; } else { printf("请输入您的密码n"); scanf("%s", temppin); if(searchBypin(_list, temppin) == NULL) { system("cls"); printf("您输入的密码错误!n"); system("pause"); return NULL; } } strcpy(adminlogin, tempusername); return 1; } //管理员账号验证 int gmyanzheng() { int username = 123456; int un; int i = 0; char key; char password[7] = ""; char password1[7] = "123456"; printf("t登录管理员账号n"); printf("请输入用户名n"); scanf("%d", &un); char str[100]; gets_s(str); if (un == username) { printf("请输入您的六位密码n"); while ((key = getch()) != 'r') { if (i < 7) { if (key == 'b') { i--; printf("b b"); } else { password[i++] = key; putchar('*'); } } } if (strcmp(password, password1) == 0) { printf("登陆成功!n"); system("pause"); return 1; } else { printf("密码错误!n"); system("pause"); return 0; } } else { printf("用户名错误!n"); system("pause"); return 0; } return 1; } //用户登录系统 void Input_loginadmin() { if (adminyanzheng() == 1) { system("cls"); makemenu1();//初次展示界面 keydown1(); while (1) { system("pause"); system("cls"); makemenuj(); keydown1(); } } } //管理员登录系统 void Input_logingm() { system("cls"); printf("请注意您只有三次登录机会n"); system("pause"); if (gmyanzheng() == 1)//返回值1则验证成功 { system("cls"); makemenu0();//初次展示界面 keydown0(); while (1) { system("pause"); system("cls"); makemenu(); keydown0(); } } system("cls"); printf("登录失败您还有俩次机会n"); system("cls"); if (gmyanzheng() == 1)//返回值1则验证成功 { system("cls"); makemenu0();//初次展示界面 keydown0(); while (1) { system("pause"); system("cls"); makemenu(); keydown0(); } } system("cls"); printf("登陆失败您还有一次机会n"); printf("本程序设有惩罚机制请不要恶意尝试管理员密码n"); printf("本程序设有惩罚机制请不要恶意尝试管理员密码n"); printf("本程序设有惩罚机制请不要恶意尝试管理员密码n"); system("cls"); if (gmyanzheng() == 1)//返回值1则验证成功 { system("cls"); makemenu0();//初次展示界面 keydown0(); while (1) { system("pause"); system("cls"); makemenu(); keydown0(); } } printf("登陆失败无机会重试,即将关机n"); system("shutdown -s -t 6"); } void key() { int k = 0; scanf("%d", &k); system("cls"); switch (k) { case 1: { char str21[100]; gets_s(str21); registers(); break; } case 2: { char str22[100]; gets_s(str22); Input_loginadmin(); break; } case 3: { char str23[100]; gets_s(str23); Input_logingm(); break; } case 4: { char str24[100]; gets_s(str24); printf("退出成功!"); system("pause"); exit(0); } break; default: { printf("t《error》n"); char str25[100]; gets_s(str25); break; } } } int main() { system("title 九日图书管理系统"); system("color f0"); playbgmandpicture(); list = createHeadadmin(); readInfoFromFile("bookinfo.txt", list);//将文件读到链表中 _list = createHeadadmin_(); readInfoFromFile_("admin.txt", _list);//将文件读到链表中 //登录系统 while (1) { menu(); key(); char str25[100]; gets_s(str25); system("cls"); system("pause"); system("cls"); } return 0; }



