图书管理系统

前言:学校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;
}
posted @   zpchcbd  阅读(154)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· 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
点击右上角即可分享
微信分享提示