图书管理系统

前言:学校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 @ 2021-12-24 21:36  zpchcbd  阅读(173)  评论(0)    收藏  举报