C语言-【图书管理系统--简易制作】

一、创建图书类型(结构体)、用户操作(枚举)、文件保存位置(宏)

// 头指针指向头节点 -- 有头节点 
// 头节点只要指针域,没有数据域

//图书类型 
typedef struct book{
	int id; // 图书编号 
	int bookNum; // 图书数量 
	char bookName[30]; // 书名 
	int hot; // 图书的热度	 
	struct book *next;
	struct book *last; 
}BOOK;

//用户操作 
typedef enum{
	ADDBOOK=1,
	DELBOOK,
	FINBOOK,
	RENTBOOK,
	RETBOOK,
	BEFBOOKINS,
	AFTBOOKINS,
	SAVEBOOK,
	HOTRANK,
	SHOWBOOK,
	INVBOOK,
	KINDBOOK,
	EXISYS=0
}UserOperation;

//文件保存位置
#define bookSavePath "./books.txt"  
#define readModel "r+t"
#define writeModel "w+t"

本图书管理系统使用链表进行操作--使用有头节点类的链表

二、声明函数

void showUI(void);// ui界面及逻辑 
int  getlenList(BOOK *h);//获取存放的了多少样图书
BOOK  *createNode(void);// 创建图书节点
void  findAll(BOOK *h); // 访问所有图书 
void  addNode(BOOK *h);// 添加图书节点
void  delNode(BOOK *h,int id);//删除图书节点
void  rentBook(BOOK *h,int id);// 修改图书节点 -- 借书 
void  returnBook(BOOK *h,int id);// 修改图书节点 -- 还书
void  hotRanking(BOOK *h);// 图书热度排行榜
BOOK *getBookById(BOOK *h,int id);//查找图书 
void insertAfterNode(BOOK *h,int id);//从某一个指定节点后面插入新节点 
void insertBeforeNode(BOOK *h,int id);//从某一个指定节点前面插入新节点
void saveToTxt(BOOK *h);// 将整个链表的信息全部写入到文件里面去 覆盖掉的
BOOK *initLinkList(void);// 链表初始化 
void inverNode(BOOK *h);//反转链表

三、主函数

调用各个子函数,利用switch-case结构启用UI界面

int main()
{    
    BOOK *h = initLinkList();
    int choice;
	int id; // 用户操作的id 
	int num; // -- 多少样图书 
	while(1)
	{
		showUI();
		
		scanf("%d",&choice);
		
		switch(choice)
		{
			case ADDBOOK:
				addNode(h);
				break;
			case DELBOOK:
				printf("请输入要删除的图书的id:");
				scanf("%d",&id);
				delNode(h,id);
				break;
			case FINBOOK: 
				printf("请输入要查找的书的id:");
				scanf("%d",&id);
				BOOK *b = getBookById(h,id);
				
				if(b == NULL)
				{
					printf("没有找到该书籍\n"); 
				}
				else
				{
					printf("%-3d %-30s %d %-3d\n",b->id,b->bookName,b->hot,b->bookNum);
				}
				break;
			case RENTBOOK:
				// 借书
				printf("请输入要借阅的书的id:");
				scanf("%d",&id);
				rentBook(h,id);
				break; 
			case RETBOOK:
				// 还书
				printf("请输入要借阅的书的id:");
				scanf("%d",&id);
				returnBook(h,id); 
				break;
			case BEFBOOKINS:
				// 在书之前插入书 
				printf("请输入要插入的书的id:");
				scanf("%d",&id);
				insertBeforeNode(h,id);
				break;
			case AFTBOOKINS:
				// 在书之后插入书 
				printf("请输入要插入的书的id:");
				scanf("%d",&id);
				insertAfterNode(h,id);
				break;
			case SAVEBOOK:
				saveToTxt(h);
				break;
			case HOTRANK:
				hotRanking(h);
				printf("=======热度排行榜======");
				findAll(h); 
				break;
			case SHOWBOOK:
				findAll(h);
				break;
			case INVBOOK:
				inverNode(h);
				findAll(h); 
				break;
			case KINDBOOK:
				num = getlenList(h);
				printf("共有%d样图书\n",num);
				break;	
			case EXISYS:
				printf("欢迎再次光临系统!"); 
				return 0;					
			default:
				printf("欢迎再次光临系统!"); 
				return 0;	
		}
	}
    return 0;
 }

四、子函数

// 访问 - 函数 
void  findAll(BOOK *h)
{
	while(h->next != NULL)
	{
		h = h->next;
		printf("%-3d %-20s %d %-3d\n" ,h->id,h->bookName,h->hot,h->bookNum);
	} 
} 

// 创建图书节点 - 函数 
// 返回值类型 BOOK *
// 函数名:createNote
// 形参:void 
BOOK *createNode(void)
{
	BOOK *p = (BOOK *)malloc(sizeof(BOOK));// 动态分配 -- 空间由程序员自己生成自己释放 -- 堆区 
		
	printf("请输入图书编号:");
	scanf("%d",&p->id);
	printf("请输入图书名:");
	scanf("%s",p->bookName);
	printf("请输入图书热度:");
	scanf("%d",&p->hot);
	printf("请输入图书的库存:");
	scanf("%d",&p->bookNum);
	 
	p->next = NULL; 
	return p;
} 

// 添加图书节点
// 返回值类型 void
// 函数名:addNote
// 形参:BOOK *h
void addNode(BOOK *h)
{ 
	while(h->next != NULL)
	{
		h = h->next;
	}
	// 创建一个新节点
	h->next = createNode();
} 

// 删除图书节点 - 通过 id 删除
// 返回值类型:void
// 函数名:delNote
// 形参:int id,BOOK *h;
void delNode(BOOK *h,int id)
{
	BOOK *p = h;
	while(h->next != NULL)
	{
		p = h;
		h = h->next;
		if(id == h->id){
			p->next = h->next;
			free(h);
			h = NULL;
			break;
		}
	}
}

// 修改图书节点 -- 借书
//	返回值类型:void
//	函数名: rentBook
//	形参:BOOK *h,int id 
void rentBook(BOOK *h,int id) 
{
	while(h->next != NULL)
	{
		h = h->next;
		if(h->id == id)
		{
			if(h->bookNum <= 0){
				printf("图书库存为0,请换其他图书借取,谢谢!\n"); 
				break;
			}else{
				h->bookNum = h->bookNum -1;
				break;	
			}
		}
	}
}

// 修改图书节点 -- 还书
//	返回值类型:void
//	函数名: rentBook
//	形参:BOOK *h,int id
void returnBook(BOOK *h,int id)
{
	while(h->next != NULL)
	{
		h = h->next;
		if(h->id == id)
		{
			h->bookNum = h->bookNum +1;
			break;
		}
	}	
} 

// 图书热度排行榜 - 1、将热度排序 or 2、节点排序 
//	返回值类型:void
//	函数名:hotRanking
//	形参:BOOK *h 
void hotRanking(BOOK *h)
{	
	// 如果链条为空 
	if(h == NULL || h->next == NULL)
	{
		return ;  // 结束函数 
	}
	int len = getlenList(h);
	BOOK *head;
	BOOK *p;
	BOOK *q;
	int i=0;
	int j=0;
	for(i=len;i>0;i--)
	{
		head = h;
		p = h;
		q = h->next;
		
		for(j=0;j<i-1;j++)
		{
			// 移动指针位置 - 将节点连线 
			 head = p;
			 p = q;
			 q = q->next; 
			 
			// p->hot q->hot
			 if(p->hot < q->hot){
			 	p->next = q->next;
				q->next = p;
				head->next = q;	
				 
				// 调整prev和p的位置
				BOOK *temp = p;
				p = q;
				q = temp; 
		}
		} 
	}
}

//void hotRanking(BOOK *h)
//{
//	int len = setlenlish(h); 
//	BOOK *q;
//	q = h;
//	int hotArr[k];
//	int idArr[k];
//	int i=0;
//    while(h->next != NULL)
//	{   
//		h = h->next;
//		hotArr[i] = h->hot;
//		idArr[i] = h->id; 
//		i++;
//	}
//	int *p =hotArr;
//	int j;
//	for(i=k;i>0;i--)
//	{
//		for(j=0;j<i-1;j++)
//		{
//			if(*(p+j) < *(p+j+1)){
//				int temp = *(p+j);
//				*(p+j) = *(p+j+1);
//				*(p+j+1) = temp;
//				temp = idArr[j];
//				idArr[j] = idArr[j+1];
//				idArr[j+1] = temp;
//			}	
//		}
//	}
//	for(i=0;i<k;i++)
//	{
//		h = q;
//		while(h->next != NULL)
//		{   
//			h = h->next;
//			if(hotArr[i] == h->hot && idArr[i] == h->id){
//				printf("%s 热度为%d\n",h->bookName,hotArr[i]);
//				break;
//			}
//			
//		}
//	}
//} 

//获取存放了多少样图书 
int getlenList(BOOK *h)
{
	int count=0;
	while(h->next != NULL)
	{
		h = h->next; 
		count++;
	}
	return count;
} 

// 查找图书 -- id
//	返回值类型:BOOK * 
//	函数名:getBookById
//	形参:BOOK *h,int id 
BOOK *getBookById(BOOK *h,int id)
{
	if(h == NULL || h->next == NULL)
	{
		return NULL;
	}
	while(1)
	{
		if(id == h->id)
		{
			return h;
		}
	}
}

// 往某个节点后面插入新节点
//	返回值类型:void
//	函数名:insertAfterNode
//	形参:BOOK *h int id
void insertAfterNode(BOOK *h,int id)
{	
	if(h == NULL || h->next == NULL)
	{
		return ;
	}
	
	while(h->next != NULL)
	{
		h=h->next;
		if(id == h->id)
		{
			BOOK *newNode = createNode();
			newNode->next = h->next;
			h->next = newNode;
			
			break;
		}
	 } 
}	 

// 往某个节点前面插入新节点
//	返回值类型:void
//	函数名:insertAfterNode
//	形参:BOOK *h int id
void insertBeforeNode(BOOK *h,int id)
{	
	if(h == NULL || h->next == NULL)
	{
		return ;
	}
	BOOK *p = h;
	BOOK *prev =h;
	while(p != NULL)
	{
		prev = p;
		p = p->next;
		if(id == p->id)
		{
			BOOK *newNode = createNode();
			
			prev->next = newNode;
			newNode->next = p;
			break;
		}
	 } 
}

// 将整个链表的信息全部写入到文件里面去 覆盖掉的
//	返回值类型:void
//	函数名:saveToTxt
//	形参:BOOK *h
void saveToTxt(BOOK *h)
{
	FILE *fp = fopen(bookSavePath,writeModel);
		
	if(fp == NULL){
		printf("文件打开失败!");
		return ;
	}
	while(h->next != NULL)
	{
		h = h->next;
		fprintf(fp,"%3d %20s %d %3d\n",h->id,h->bookName,h->hot,h->bookNum);
	}											
}

// 链表的初始化
// 返回值类型:BOOK *
// initLinkList
// 形参:void
BOOK *initLinkList(void)
{
	char ch;
	//生成头结点
	BOOK *h = (BOOK *)malloc(sizeof(BOOK));
	h->next = NULL;
	
	BOOK *p = h;
	//文件里面读取信息挂在到头节点的后面
	FILE *fp = fopen(bookSavePath,readModel);
	if(fp == NULL){
		return NULL;
	}
	ch = fgetc(fp);
	// 到文件的结尾
	// 检测文件是否为空 
	if(ch == EOF) 
	{
		fclose(fp);
		return h;
	} 
	rewind(fp);
	while(feof(fp) == 0)
	{	
		
		BOOK *newNode = (BOOK *)malloc(sizeof(BOOK));
		newNode->next = NULL;
		fscanf(fp,"%3d %20s %d %3d\n",&newNode->id,newNode->bookName,&newNode->hot,&newNode->bookNum);
		
		p->next = newNode;
		p = newNode;
		
	} 
	fclose(fp);
	
	return h; 
 } 

//UI界面设计 
void showUI(void)
{
	printf("================欢迎来到图书管理系统=================\n");
	printf("================[1]添加     [2]删除图书==============\n"); 
	printf("================[3]检索     [4]借书==================\n"); 
	printf("================[5]还书     [6]前插入================\n"); 
	printf("================[7]后插入   [8]保存==================\n"); 
	printf("================[9]热度排行榜 [10]查看所有图书=======\n"); 
	printf("==============[11]反转图书列表[12]获取图书数量=======\n");
	printf("请选择:");
}

//反转整个图书的排序 
void inverNode(BOOK *h)
{
	if( h == NULL || h->next == NULL || h->next->next == NULL)
	{
		return ;
	 }
	BOOK *q = h;
	BOOK *p = h->next;
	BOOK *prev = h->next->next;
//	h->next->next = NULL;
//	h->next = p;
		while(1)
		{
			// 改变方向 
			p->next = q;
	
			if(prev == NULL){
				h->next->next = NULL;
				h->next = p;
				break; 
			} 
			// 三个指针移动 
			q = p;
			p = prev;
			prev = prev->next;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值