图书管理系统
前言:学校C的作业,今天自己写了下,这里做个记录
1、存储对象有两个,一个是图书,一个是借书证
2、图书的话存储方式为数组,借书证存储的方式为链表
3、封装了4个模块,分别是图书、借书证、文件、公共
主函数
#include "c_public.h" #include "c_m_book.h" int gBookNum; Book gBooks[BOOKNUM]; void getBanner(); void getMenu(); void getConsole(); void getBanner(){ printf("\t\t图书管理系统\n\n\n"); } void getMenu(){ printf("-操作选单-\n\n"); printf("用数字选择操作\n"); printf("\t\t1图书信息录入\t2显示图书\n"); printf("\t\t3查询图书信息\t4修改图书信息\n"); printf("\t\t5删除图书\t6借阅图书\n"); printf("\t\t7归还图书\t8退出系统\t\t\n"); } void getConsole(){ system("cls"); getBanner(); getMenu(); printf("请按数字键:"); } void getPause(){ system("pause"); getchar(); } int main(int argc, char* argv[]){ int initFlag = 1; if (initBooks()){ while (initFlag){ getConsole(); char option; scanf(" %c", &option); system("cls"); getBanner(); switch (option) { case '1': { // addBook addBook(); system("pause"); break; } case '2': // showBook showBook(); system("pause"); break; case '3': // findBook findBook(); system("pause"); break; case '4': // editBook editBook(); system("pause"); break; case '5': // deleteBook deleteBook(); system("pause"); break; case '6': // borrowBook borrowBook(); system("pause"); break; case '7': // returnBook returnBook(); system("pause"); break; case '8': initFlag = 0; saveBooks(); break; default: printf("please input again\n"); break; } } } releaseAllCardLinkMemory(); return 0; }
图书模块
c_m_book.h
#ifndef BOOK_H_H #define BOOK_H_H #include "c_public.h" #include "c_m_card.h" #define BOOKSIZE sizeof(Book) typedef struct _Book { unsigned int bookId; unsigned char bookName[16]; unsigned char bookAuthor[16]; unsigned char publisher[16]; unsigned int remainBookNum; unsigned int totalBookNum; unsigned int bookCardNum; PCard Card; } Book, *PBook; int isExist(Book* currentBook, int type, char* bookName, unsigned bookId); int isExistBaseBook(Book* book); int isExistBaseBookName(char* bookName); int isExistBaseBookId(unsigned int bookId); void showBook(); void addBook(); void deleteBook(); void findBook(); void editBook(); void borrowBook(); void returnBook(); int initBooks(); int saveBooks(); #endif
c_m_book.c
#include "c_m_book.h" #include "c_m_file.h" extern int gBookNum; extern Book gBooks[BOOKNUM]; int isExist(Book* currentBook, int type, char* bookName, unsigned currentBookId){ int index = 0; if (type == 0) { for (; index<gBookNum; index++){ if (currentBook->bookId == gBooks[index].bookId) return index; } } else if (type == 1){ for (; index<gBookNum; index++){ if (strcmp(bookName, gBooks[index].bookName)==0) return index; } } else if (type == 2){ for (; index<gBookNum; index++){ if (currentBookId == gBooks[index].bookId) return index; } } return FALSE; } int isExistBaseBook(Book* book){ return isExist(book, 0, NULL, 0); } int isExistBaseBookName(char* bookName){ return isExist(NULL, 1, bookName, 0); } int isExistBaseBookId(unsigned int bookId){ return isExist(NULL, 2, NULL, bookId); } void showBook(){ int index = 0; for (; index<gBookNum; index++){ printf("序号:%d\t书名:%-15s\t作者:%-8s\t出版社:%-8s\t存数:%02d\t总数:%02d\n", gBooks[index].bookId, gBooks[index].bookName, gBooks[index].bookAuthor, gBooks[index].publisher, gBooks[index].remainBookNum, gBooks[index].totalBookNum); printf("\n"); } } void addBook(){ char option; int currentBookId = -1; int addBookNum; char szBuffer[_MAX_PATH]; Book book = { 0 }; showBook(); printf("添加书本格式:序号[空格]书名[空格]作者名[空格]出版单位[空格]数量\n\n"); do{ memset(szBuffer, 0, _MAX_PATH); gets(szBuffer); if (szBuffer[0] == '\0')break; sscanf(szBuffer, "%d %s %s %s %d", &book.bookId, book.bookName, book.bookAuthor, book.publisher, &addBookNum); if ((currentBookId = isExistBaseBook(&book))==-1){ /*if (!book.remainBookNum || !book.totalBookNum) book.remainBookNum = book.totalBookNum = 0; */ // 这里如果录入成功,还需要修正图书的存储数量 book.remainBookNum = addBookNum; book.totalBookNum = addBookNum; book.bookCardNum = 0; gBooks[gBookNum] = book; gBookNum++; printf("录入成功, 是否接着输入下一个图书(Y/N): "); } else{ gBooks[currentBookId].totalBookNum += addBookNum; gBooks[currentBookId].remainBookNum += addBookNum; printf("录入成功, 重复, 是否接着输入下一个图书(Y/N): "); } scanf("%c", &option); getchar(); } while (option == 'Y'); } void findBook(){ char szBuffer[_MAX_PATH]; int currentBookId = -1; memset(szBuffer, 0, _MAX_PATH); printf("请输入书名: "); scanf("%s", &szBuffer); if ((currentBookId = isExistBaseBookName(szBuffer)) != -1){ printf("序号:%d\t书名:%-15s\t作者:%-8s\t出版社:%-8s\t存数:%02d\t总数:%02d\n", gBooks[currentBookId].bookId, gBooks[currentBookId].bookName, gBooks[currentBookId].bookAuthor, gBooks[currentBookId].publisher, gBooks[currentBookId].totalBookNum, gBooks[currentBookId].remainBookNum); } else{ printf("无此书!\n"); } } void deleteBook(){ int index = 0; int BookId; int currentBookId = -1; showBook(); printf("请输入要删除的图书编号: "); scanf("%d", &BookId); if ((currentBookId = isExistBaseBookId(BookId))!=-1){ releaseCardLinkMemory(&gBooks[currentBookId].Card); if (gBookNum == 1 || (gBookNum - 1 == currentBookId && gBookNum > 1)) memset((void*)&gBooks[gBookNum - 1], 0, BOOKSIZE); else{ for (; currentBookId < gBookNum; currentBookId++) gBooks[currentBookId] = gBooks[currentBookId + 1];// 2 3 / 3 4 / 4 5/ } gBookNum--; } else{ printf("没有你想要删除的图书编号!\n"); } } void editBook(){ int index = 0; int BookId; int currentBookId = -1; int addBookNum; showBook(); printf("-修改图书信息:-\n\n"); printf("输入要修改的图书id:"); scanf("%d", &BookId); if ((currentBookId = isExistBaseBookId(BookId)) != -1){ printf("序号:%d\t书名:%-15s\t作者:%-8s\t出版社:%-8s\t存数:%02d\t总数:%02d\n\n", gBooks[currentBookId].bookId, gBooks[currentBookId].bookName, gBooks[currentBookId].bookAuthor, gBooks[currentBookId].publisher, gBooks[currentBookId].remainBookNum, gBooks[currentBookId].totalBookNum); printf("修改书本格式:书名[空格]作者名[空格]出版单位[空格]数量\n\n"); scanf("%s %s %s %d", &gBooks[currentBookId].bookName, &gBooks[currentBookId].bookAuthor, &gBooks[currentBookId].publisher, &addBookNum); // 稍微进行逻辑验证 if (gBooks[currentBookId].bookCardNum <= addBookNum) { gBooks[currentBookId].remainBookNum = addBookNum - gBooks[currentBookId].bookCardNum; gBooks[currentBookId].totalBookNum = addBookNum; printf("修改图书信息成功\n"); printf("修改后该编号 %d 的图书信息:\n", currentBookId+1); printf("序号:%d\t书名:%-15s\t作者:%-8s\t出版社:%-8s\t存数:%02d\t总数:%02d\n", gBooks[currentBookId].bookId, gBooks[currentBookId].bookName, gBooks[currentBookId].bookAuthor, gBooks[currentBookId].publisher, gBooks[currentBookId].remainBookNum, gBooks[currentBookId].totalBookNum); } else{ printf("删除失败!\n"); } } else{ printf("没有你想要删除的图书编号!\n"); } } void borrowBook(){ int currentBookId = -1; char szBuffer[_MAX_PATH]; PCard pCard = (PCard)malloc(CARDSIZE); PCard p = NULL; memset(pCard, 0, CARDSIZE); showBook(); printf("请输入要借阅的书名:"); scanf("%s", &szBuffer); if ((currentBookId = isExistBaseBookName(szBuffer)) != -1){ printf("%s %s %s %d %d\n", gBooks[currentBookId].bookName, gBooks[currentBookId].bookAuthor, gBooks[currentBookId].publisher, gBooks[currentBookId].remainBookNum, gBooks[currentBookId].totalBookNum); printf("输入借书证序号:"); scanf("%d", &pCard->cardId); printf("输入可借天数:"); scanf("%d", &pCard->cardBorrowDay); getLastPCard(gBooks[currentBookId].Card, &p); if (p == NULL) gBooks[currentBookId].Card = pCard; else p->next = pCard; gBooks[currentBookId].bookCardNum++; gBooks[currentBookId].remainBookNum--; printf("借阅成功!\n"); } else{ printf("没有你想要借阅的图书名称!\n"); } } void returnBook(){ int currentBookId = -1; char szBuffer[_MAX_PATH]; int deleteCardId; showBook(); printf("请输入要归还的书名:"); scanf("%s", &szBuffer); if ((currentBookId = isExistBaseBookName(szBuffer)) != -1){ printf("%s %s %s %d %d\n", gBooks[currentBookId].bookName, gBooks[currentBookId].bookAuthor, gBooks[currentBookId].publisher, gBooks[currentBookId].remainBookNum, gBooks[currentBookId].totalBookNum); if ((gBooks[currentBookId].Card == NULL ? 1 : 0)) { printf("该图书无相关的借书信息!\n"); return; } showCard(gBooks[currentBookId].Card); printf("\n"); printf("输入借书证序号:"); scanf("%d", &deleteCardId); printf("\n"); deleteCardById(&gBooks[currentBookId].Card, deleteCardId, gBooks[currentBookId].bookCardNum); gBooks[currentBookId].bookCardNum--; gBooks[currentBookId].remainBookNum++; if (gBooks[currentBookId].bookCardNum == 0) printf("全部归还!\n"); else printf("归还成功!\n"); } else{ printf("没有你想要归还的图书名称!\n"); } } int initBooks(){ int iLine = 0; int index = 0; FILE* pFile = NULL; PCard pCard = NULL; PCard p = NULL; unsigned char szBuffer[1024]; char* pToken = NULL; memset(szBuffer, 0, 1024); if (getFileHandle(&pFile, FILENAME, "a+")){ if (getFileLine(pFile, &iLine)){ gBookNum = iLine; memset(gBooks, 0, BOOKSIZE*BOOKNUM); fseek(pFile, 0, SEEK_SET); while (index != iLine) { pToken = NULL; fscanf(pFile, "%d %s %s %s %d %d %d %s", &gBooks[index].bookId, gBooks[index].bookName, gBooks[index].bookAuthor, gBooks[index].publisher, &gBooks[index].remainBookNum, &gBooks[index].totalBookNum, &gBooks[index].bookCardNum, szBuffer); // szBuffer[strlen(szBuffer)] = '\0'; if (*(char*)szBuffer != '0'){ pToken = strtok(szBuffer, "-"); int bookCardIndex = 0; while (pToken != NULL) { pCard = (PCard)malloc(CARDSIZE); pCard->next = NULL; int* szArgs = getDelimCharArr2(pToken, "_"); pCard->cardId = szArgs[0]; pCard->cardBorrowDay = szArgs[1]; getLastPCard(gBooks[index].Card, &p); if (p == NULL) gBooks[index].Card = pCard; else p->next = pCard; pToken = strtok(NULL, "-"); } } index++; } closeFileHandle(&pFile); } } return TRUE; } int saveBooks(){ FILE* pFile = NULL; PCard pCard = NULL; int bookIndex = 0; int cardIndex; int nullFlag; char szBuffer[1024]; char szStr[16]; if (getFileHandle(&pFile, NEWFILENAME, "w")) { while (*(int*)(&gBooks[bookIndex])){ memset(szBuffer, 0, 1024); memset(szBuffer, 0, 16); nullFlag = 1; cardIndex = 0; strcat(szBuffer, _itoa(gBooks[bookIndex].bookId, szStr, 10)); strcat(szBuffer, " "); strcat(szBuffer, gBooks[bookIndex].bookName); strcat(szBuffer, " "); strcat(szBuffer, gBooks[bookIndex].bookAuthor); strcat(szBuffer, " "); strcat(szBuffer, gBooks[bookIndex].publisher); strcat(szBuffer, " "); strcat(szBuffer, _itoa(gBooks[bookIndex].remainBookNum, szStr, 10)); strcat(szBuffer, " "); strcat(szBuffer, _itoa(gBooks[bookIndex].totalBookNum, szStr, 10)); strcat(szBuffer, " "); strcat(szBuffer, _itoa(gBooks[bookIndex].bookCardNum, szStr, 10)); strcat(szBuffer, " "); pCard = gBooks[bookIndex].Card; while (1){ // 1_60-2_50-3_40 nullFlag = 0; strcat(szBuffer, _itoa(pCard->cardId, szStr, 10)); strcat(szBuffer, "_"); strcat(szBuffer, _itoa(pCard->cardBorrowDay, szStr, 10)); strcat(szBuffer, "-");// [ ] [-] //cardIndex++; if (pCard->next == NULL) { break; } pCard = pCard->next; } if (nullFlag) strcat(szBuffer, "0"); strcat(szBuffer, "\n"); szBuffer[strlen(szBuffer)] = '\0'; bookIndex++; fwrite(szBuffer, strlen(szBuffer), 1, pFile); } closeFileHandle(&pFile); } return TRUE; }
借书证模块
c_m_card.h
#ifndef CARD_H_H #define CARD_H_H #include "c_public.h" #define CARDSIZE sizeof(Card) typedef struct _Card{ unsigned int cardId; //unsigned char cardBorrowBookName[16]; unsigned int cardBorrowDay; struct _Card* next; } Card, *PCard; int getIndexByCardId(unsigned int cardId, PCard cardArr[]); void deleteCardById(PCard* pCard, unsigned int cardId, unsigned int cardLength); void getLastPCard(PCard pCard, PCard* p); void showCard(PCard pCard); void releaseCardLinkMemory(PCard* pCard); void releaseAllCardLinkMemory(); #endif
c_m_card.c
#include "c_m_card.h" #include "c_m_book.h" extern Book gBooks[BOOKNUM]; int getIndexByCardId(unsigned int cardId, PCard cardArr[]){ int cardIndex = 0; while (cardArr[cardIndex]){ if (cardArr[cardIndex]->cardId == cardId) return cardIndex; cardIndex++; } } void getLastPCard(PCard pCard, PCard* p){ *p = pCard; if (*p != NULL) { while ((*p)->next){ (*p) = (*p)->next; } } } void showCard(PCard pCard){ PCard p = NULL; p = pCard; if (p != NULL) { while (1){ printf("[%d]--%d天\n", p->cardId, p->cardBorrowDay); if (p->next == NULL) { break; } p = p->next; } } } void deleteCardById(PCard* pCard, unsigned int cardId, unsigned int cardLength){ PCard p = NULL; PCard pCardPrev = NULL; p = *pCard; pCardPrev = p; int index = 1; if (cardLength == 0) { printf("该图书没有相关的借书证信息!"); return; } if (p != NULL) { while (1){ if (p->cardId == cardId){ break; } pCardPrev = p; p = p->next; index++; } }else{ printf("该图书没有相关的借书证信息!"); return; } if (index == 1 && cardLength == 1) { // 删除是第一个,并且数量只有一个 free(p); p = NULL; }else if(index == 1 && cardLength > 1){ // 删除的是第一个,但是数量不是只有一个 *pCard = p->next; }else if (index == cardLength && cardLength > 1){ // 删除的是最后一个 free(pCardPrev->next); pCardPrev->next = NULL; }else{ // 删除的是中间 p = p->next; free(pCardPrev->next); pCardPrev->next = NULL; pCardPrev->next = p; } } void releaseCardLinkMemory(PCard* pCard){ PCard p1 = NULL; PCard p2 = NULL; p1 = *pCard; p2 = p1->next; while (1) { free(p1); p1 = NULL; p1 = p2; p2 = p2->next; if (p2->next == NULL){ free(p2); free(p1); p1 = NULL; p2 = NULL; break; } } *pCard = NULL; } void releaseAllCardLinkMemory(){ int index = 0; while (*(int*)&gBooks[index]){ releaseCardLinkMemory(&gBooks[index].Card); index++; } }
文件模块
c_m_file.h
#ifndef FILE_H_H #define FILE_H_H #include "c_public.h" int getFileHandle(FILE** pFile, const char* fName, const char* fMode); int closeFileHandle(FILE** pFile); int getFileLine(FILE* pFile, int* iLine); #endif
c_m_file.c
#include "c_m_file.h" int getFileHandle(FILE** pFile, const char* fName, const char* fMode){ *pFile = fopen(fName, fMode); if (*pFile == NULL) { printf("[-] open file fail\n"); exit(0); } fseek(*pFile, 0, SEEK_SET); return TRUE; } int closeFileHandle(FILE** pFile){ if (*pFile != NULL) { fclose(*pFile); *pFile = NULL; return TRUE; } return FALSE; } int getFileLine(FILE* pFile, int* iLine){ while (!feof(pFile)) { if (fgetc(pFile) == '\n') (*iLine)++; } if (iLine == 0) { fclose(pFile); return FALSE; } return TRUE; }
公共模块
c_public.h
#ifndef PUBLIC_H_H #define PUBLIC_H_H #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> // #include <windows.h> #define BOOKNUM 999 #define BOOKCARDNUM 16 #define FILENAME "D:\\Visual_Studio_Repos_2013\\图书馆管理系统\\Debug\\book.txt" #define NEWFILENAME "D:\\Visual_Studio_Repos_2013\\图书馆管理系统\\Debug\\book.txt" #define TRUE 1 #define FALSE -1 #define ERROR 0 int* getDelimCharArr(char szBuffer[], const char* Delim); int* getDelimCharArr2(char szBuffer[], const char* Delim); #endif
c_public.c
#include "c_public.h" int* getDelimCharArr(char szBuffer[], const char* Delim){ char* pToken = NULL; int szArgs[2]; int index = 1; char szTokenBuffer[1024]; memset(szTokenBuffer, 1024, 0); memcpy(szTokenBuffer, szBuffer, 1024); pToken = strtok(szTokenBuffer, Delim); while (pToken != NULL) { if (index == 1) szArgs[0] = atoi(pToken); else if (index == 2) szArgs[1] = atoi(pToken); pToken = strtok(NULL, Delim); index++; } return szArgs; } int* getDelimCharArr2(char szBuffer[], const char* Delim){ int szArgs[2]; sscanf(szBuffer, "%d_%d", &szArgs[0], &szArgs[1]); return szArgs; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
2019-12-24 学习:VB之p-code寻找操作数
2019-12-24 Domain Cached Credentials