C语言完成图书管理系统

 

 引言:这个系统是我大一下册编写的,也没有再修改,C语言只学到简单的指针为止,对C的认识非常肤浅,并且没有代码经验,可以说这是我第一个能算上能实现功能的系统,仅仅借助书籍:程序设计第四版(谭浩强)、数据结构(清华大学出版社 C语言版),因此对于只要学过C语言的同学都应该能看明白,希望大家勿喷。注:程序配大量注释

  •  主要知识点:结构体、单链表、循环、break、continue、strcmp(字符串比较)、fopen fwrite fclose(数据存储)等。
  •  系统缺点:代码特别冗杂,有很多具有相似功能的没有整合;函数与函数之间只有单纯的地址传递;简单算法也是嵌套了太多循环,并没有从本质上优化算法。
  • 系统优点(功能):拥有简单的交互界面;实现了系统的借书、还书、查找书籍、增添、删除、修改书籍的具体功能;并对每次启动系统进行数据录入和数据存储(前提:按系统正常退出);并对各项功能的误操作进行简单的报错提示;
  • 如图

         C语言完成图书管理系统_第1张图片               C语言完成图书管理系统_第2张图片

 

  • 代码
/*
作品:图书管理系统
出品人:小汪 
时间:2018/6/1
*/
#include 
#include 
#include 
#include
struct book                //书籍信息
{
	int num;           //编号
	char name[20];     //书名称
	char location[50];       //存放位置
};
struct book_date                  //存放书籍的方式(链表)
{
	struct book date;
	struct book_date *next;
};
/*顺序表建立
*/
int manage_menu();  //管理员菜单
struct book_date * linklist_book();    //创建链表 
void putin_book(struct book_date *);   //增加书籍 
void change_book_information(struct book_date *);    //修改或删除图书信息
void all_book(struct book_date *);// 显示所有图书基本信息
int  Return_operation();         
void borrow_book(struct book_date *);                  //借书 
void return_book(struct book_date *);          //还书 
void get_only_oneworld(); //规定输入选项符号
int Main_menu();//主菜单
void put_date(struct book_date *); //预览图书
struct book_date * L;//指向头节点
void save_information(struct book_date *L); //录入数据 声明
void read_information(struct book_date *L); // 读取数据 声明

/*主函数
*/
int main()
{
	L = linklist_book();
	read_information(L);
	Main_menu();
	save_information(L);
	return 0;
}

/*定输入选项符号
*/
void get_only_oneworld()
{
	while (getchar() != '\n')
	{
		continue;
	}
}


/* 链表初始化
*/
struct book_date *linklist_book()
{
	struct book_date *head, *p;
	p = (struct book_date *)malloc(sizeof(struct book_date));
	if (p != NULL)        //头节点分配成功
	{
		head = p;
		p->next = NULL;
	}
	return head;
}

/*图书入库
*/
void putin_book(struct book_date *L)
{
	system("cls");
	int number = 0;//本次录入的数量
	struct book_date *last, *now;
	last = L;
	while (last->next != NULL)		last = last->next;//迭代到最后,可利于多次分批录入
	printf("* * * * * * * * 图书正在入库中 * * * * * * * *\n");
	printf("\n");
	printf("# # # 结束本次录入请输入0 # # # \n");
	printf("\n");
	while (1)
	{
		now = (struct book_date *)malloc(sizeof(struct book_date));
		printf("请输入书籍名称: ");
		scanf("%s", now->date.name);
		getchar();
		if (strcmp(now->date.name, "0") == 0)
		{
			free(now);
			break;
		}
		printf("请输入书籍编号: ");
		scanf("%d", &now->date.num);
		getchar();
		if (now->date.num == 0)
		{
			free(now);
			break;
		}
		printf("请输入取书的所在位置: ");
		scanf("%s", now->date.location);
		getchar();
		if (strcmp(now->date.location, "0") == 0)
		{
			free(now);
			break;
		}
		printf("\n");
		last->next = now;
		last = now;
		++number;//本次录入的数量
	}
	last->next = NULL;
	printf("\n");
	printf("* * * * * * * * * * * * * * * * * * *\n");
	printf("*                                   *\n");
	printf("*     图 书 馆 新 增 书 籍 %d\n", number);
	printf("*                                   *\n");
	printf("* * * * * * * * * * * * * * * * * * *\n");
	printf("\n");
	printf("* * * * * * * * 录入完成!* * * * * * * * \n");
	Return_operation();
}

/*修改或删除图书信息
*/
void change_book_information(struct book_date *L)
{
	system("cls");
	char celect[10];
	int num;          //修改书籍的编号
	char b[20];
	char flag[20];          // 继续修改(确认1,否则0)
	struct book_date *p, *previous;        //previous为要被修改数据的前一个节点
	int fail = 3;
	int ok = 0;         // 判断循环是否跳出
	p = L;
	printf("* * * * * * * * 确认图书信息进行下列操作 * * * * * * * *\n");
	do
	{
		p = L;
		do
		{
			printf("请 输 入 查 询 图 书 的 编 号:");
			scanf("%d", &num);
			getchar();
			while (p->next != NULL)                  //找到编号相同的节点              
			{
				previous = p;
				p = p->next;
				if (p->date.num == num)
				{
					ok = 1;
					break;
				}
			}
			if (ok == 0)                            //没有找到就重新输入
			{
				printf("未 找 到 此 类 图 书!!! \n");
				printf(" (剩余%d次)", --fail);
				p = L;
			}
			else
			{
				printf("图 书 原 信 息 :\n");
				printf("编号:%d \t《%s》\t 位置:%s\n", p->date.num, p->date.name, p->date.location);
				printf("输入1:修改信息\n");
				printf("输入2:删除书籍\n");
				printf("输入任意字符:退出操作");
				printf("\t ##请输入:");
				scanf("%s", celect);
				getchar();
				if (strcmp(celect, "1") == 0)
				{
					printf("# 请 重 新 输 入 书 籍 相 关 信 息 (系统自动覆盖旧信息) #\n");
					printf("编 号 :");
					scanf("%d", &num);
					getchar();
					p->date.num = num;
					printf("书 名 :");
					scanf("%s", b);
					getchar();
					strcpy(p->date.name, b);
					printf("存 放 位 置 :");
					scanf("%s", b);
					getchar();
					strcpy(p->date.location, b);
					break;
				}
				if (strcmp(celect, "2") == 0)
				{
					previous->next = p->next;
					free(p);
					break;
				}
				if (strcmp(celect, "1") != 0 || strcmp(celect, "2") != 0)
				{
					break;
				}
			}
		} while (fail != 0);
		if (fail == 0)
		{
			break;
		}
		else
		{
			printf("* * * * * * * * * * * * 修改完成 * * * * * * * * * * * *\n");
			printf("继续输入1,否则任意字符:");
			scanf("%s", flag);
			getchar();
			printf("\n");
		}
	} while (strcmp(flag, "1") == 0);
	if (fail == 0)
	{
		printf("请 尽 快 联 系 相 关 负 责 人 ! ! !\n");
		printf("! ! ! ! ! ! ! ! 修改失败 ! ! ! ! ! ! ! ! \n");
	}
	Return_operation();
}


/*借书
*/
void borrow_book(struct book_date *L)
{
	system("cls");
	char phone[20];
	int number;
	char garden[20];
	char name[20];
	int i;  // 记录错误次数
	struct book_date *p;
	printf("* * * * * * * * 正在进行借书操作 * * * * * * * *\n");
	printf("欢 迎 来 到 小 汪 书 店!!!\n");
	if (L->next == NULL)
		printf("暂 无 书 可 借 阅 ,请 等 待 管 理 员 录 入 书 籍\n");
	else
	{
		printf("请 输 入 你 想 借 阅 书 籍 的 编 号:");
		scanf("%d", &number);
		getchar();
		i = 3;
		do   //有3次重新输入机会 
		{
			p = L->next;                             //p指向头节点
			while (p != NULL)              //循环到最后一个节点
			{
				if (number == p->date.num)                   //如果当前节点相等,就跳出循环
					break;
				else
					p = p->next;
			}
			if (p == NULL)               //判断结束条件,是跳出循环还是正常走出循环
			{
				printf("输 入 错 误 !未 录 入 此 编 号!\n");
				printf("请 重 新 输 入 编 号(剩余操作次数%d):", i--);
				scanf("%d", &number);
				getchar();
			}
			else
			{
				strcpy(p->date.location, "已借出");                    //借出书过后,借书位置显示为:在其他读者手中 
				break;
			}
		} while (i != 0);                  //有5次输入正确编码的机会
		if (i == 0)
		{
			printf("! ! ! ! ! ! ! ! 为保证其他读者正常借阅,请尽快联系管理员 ! ! ! ! ! ! ! ! \n");
		}
		else
		{
			printf("* * * * * * * * 请输入你本人的基本信息 * * * * * * * *\n");
			printf("\n");
			printf(" 请 输 入 姓 名 :");
			scanf("%s", name);
			getchar();
			printf(" 请 输 入 预 留 电  话 号 码:");
			scanf("%s", phone);
			getchar();
			printf(" 请 输 人 你 所 在 年 级:");
			scanf("%s", garden);
			getchar();
			printf("\n 系 统 正 在 为 您 办 理 借 书 手 续 请 稍 后 ......\n");
			printf("* * * * * * * * * * * 借书成功 * * * * * * * * * * * *\n");
		}
	}
	Return_operation();
}

//还书
void return_book(struct book_date *L)
{
	system("cls");
	struct book_date *p, *p1;          //p是查询编号书籍信息地址,p1是查询是否有与输入位置相同的书籍地址
	int number;
	int i = 3;     //错误输入编号的次数
	p = L->next;
	if (p==NULL)
	{
		printf("最 近 未 借 出 图 书 , 若 有 疑 问 请 联 系 管 理 员!!!!!\n              联 系 方 式:xxxxxxxx\n");
	}
	else
	{
		printf("亲 爱 的 读 者!\n");
		printf("请 输 入 你 所 要 归 还 书 籍 的 编 号 :");
		scanf("%d", &number);
		do
		{
			while (p!= NULL)          //查找与编号相对应的书籍资料
			{
				if (p->date.num == number && strcmp(p->date.location, "已借出") == 0)          //找到了书籍
				{
					break;
				}
				p = p->next;
			}

			if (p == NULL)
			{
				i--;
				printf("\n\n");
				printf("输 入 不 正 确 !未 录 入 此 编 号!\n");
				printf("请 重 新 输 入 书 籍 编 号 (剩余操作次数%d):", i);
				scanf("%d", &number);
				getchar();
				p = L->next;
			}
			else
			{
				printf("\n编号:%d  书名:《%s》\t", p->date.num, p->date.name);
				printf("输入新位置:");
				scanf("%s", p->date.location);
				getchar();
				break;
			}
		} while (i != 0);

		if (i != 0)
		{
			printf("* * * * * * * * 归还成功 * * * * * * * *\n");
		}
		else
		{
			printf("! ! ! ! ! ! ! ! 为保证其他读者正常借阅,请尽快联系管理员 ! ! ! ! ! ! ! ! \n");
		}
	}
	Return_operation();
}



//读取数据
void read_information(struct book_date *L)
{
	char c;
	FILE *f1;
	struct book_date *p, *p1;
	if ((f1 = fopen("test1", "rb")) != NULL)
	{
		p = L;
		while (1)
		{
			p1 = (struct book_date *)malloc(sizeof(struct book_date));
			fread(p1, sizeof(struct book), 1, f1);
			if (feof(f1))
			{
				free(p1);
				break;
			}
			p->next = p1;
			p = p1;
		}
		p->next = NULL;
		fclose(f1);
	}
}


//录入数据
void save_information(struct book_date *L)
{
	struct book_date *p;
	FILE *fp;
	if ((fp = fopen("test1", "wb")) != NULL)
	{
		p = L;
		while (p->next != NULL)
		{
			p = p->next;
			fwrite(&p->date, sizeof(struct book), 1, fp);
		}
		fclose(fp);
	}
}



/*现存书籍
*/
void now_book(struct book_date *L)
{
	int n = 0;
	struct book_date *p;
	p = L;
	while (p->next != NULL)
	{
		p = p->next;
		if (strcmp(p->date.location, "已借出") != 0)
		{
			printf("编号:%d \t《%s》\t 位置:%s\n", p->date.num, p->date.name, p->date.location);
			n++;
		}
	}
	printf("\n");
	printf("**************************\n");
	printf("*                        *\n");
	printf("*   现 存 书 籍 共 %d 册  *  \n", n);
	printf("*                        *\n");
	printf("**************************\n");
	printf("\n");
}

/*统计书籍数量
*/
void  Statistical_books(struct book_date *L)
{
	int n = 0;                           //总书籍数量
	struct book_date *p;
	p = L;
	while (p->next != NULL)
	{
		p = p->next;
		n++;                       //存在一个节点n+1
	}
	printf("* * * * * * * * * * * * * * * * * * *\n");
	printf("*                                   *\n");
	printf("*  本 图 书 馆 图 书 现 共 计 %d 册 *\n", n);
	printf("*                                   *\n");
	printf("* * * * * * * * * * * * * * * * * * *\n\n");

}

/*借出书籍统计
*/
void lend_book(struct book_date *L)
{
	int n = 0;                     //借出书籍数量
	struct book_date *p;
	p = L;
	while (p->next != NULL)
	{
		p = p->next;
		if (strcmp(p->date.location, "已借出") == 0)
		{
			printf("编号:%d \t《%s》\t 位置:%s\n", p->date.num, p->date.name, p->date.location);
			n++;
		}
	}
	printf("\n");
	printf("**************************\n");
	printf("*                        *\n");
	printf("* 已 借 出 书 籍 共 %d 册*\n", n);
	printf("*                        *\n");
	printf("**************************\n");
	printf("\n");
}

/**/
/*预览图书
*/
void put_date(struct book_date *L)
{
	struct book_date *p;
	int number;
	char server;
	p = L->next;
	if (p == NULL)                  //如果还未录入书籍时查询结果
	{
		printf("本 书 店 还 未 录 入 书 籍 , 请 等 待 管 理 员 录 入 书 籍\n");
	}
	else
	{
		printf("* * * * * * * * 查找书籍 * * * * * * * *\n");
		printf("亲 爱 的 读 者 请 输 入 你 想 预 览 书 籍 的 编 号:");
		scanf("%d", &number);
		getchar();
		do
		{
			if (number == p->date.num)
				break;
			else
				p = p->next;
		} while (p != NULL);

		if (p == NULL)
		{
			printf("\n");
			printf("未 找 到 此 书 籍 , 请 核 对 编 号\n");
		}
		else
		{
			printf("\n");
			printf("编号:%d \t《%s》\t 位置:%s\n", p->date.num, p->date.name, p->date.location);
		}
	}
	printf("* * * * * * * * 查找完成* * * * * * * *\n\n");
}





/*主菜单
*/
int Main_menu()
{
	system("cls");
	printf("* * * * *  HPE图书馆  * * * * *\n");
	printf("\n");
	printf("  A . 管 理 员 入 口\n");
	printf("\n");
	printf("  B . 借 书 \n");
	printf("\n");
	printf("  C . 还 书 \n");
	printf("\n");
	printf("  D . 查 看 图 书 信 息\n");
	printf("\n");
	printf("  E . 退出\n");
	printf("* * * * * * * * * * * * * * * *\n");
	char server;
	printf("请 选 择 你 所 需 要 的 服 务 :");

	do
	{
		server = getchar();
		get_only_oneworld();                //清楚字符缓存区,只让getchar识别第一个字符
		switch (server)
		{
		case 'A': manage_menu(); break;
		case 'B':borrow_book(L); break;
		case 'C':return_book(L); break;
		case 'D': all_book(L); break;
		case 'E': break;
		default:printf("\t\t\t\t\t\t\t\t\t请 选 择 你 所 需 要 的 服 务 :");
		}
	} while (server != 'E' && server != 'A' && server != 'B' && server != 'C' && server != 'D');
	return 0;
}

/*管理员菜单
*/
int manage_menu()
{
	system("cls");
	printf("* * * * * 管理员选项 * * * * *\n");
	printf("A . 图 书 入 库\n");
	printf("\n");
	printf("B . 修 改 或 删 除 图 书 信 息\n");
	printf("\n");
	printf("C . 返 回 主 菜 单\n");
	printf("* * * * * * * * * *  * * * * *\n");
	char server1;
	do
	{
		printf(" *请选择你所需要的服务* :");
		server1 = getchar();
		get_only_oneworld();                  //清楚字符缓存区,只让getchar识别第一个字符
		switch (server1)
		{
		case 'A':putin_book(L); break;
		case 'B':change_book_information(L); break;
		case 'C': Main_menu(); break;
		default:printf("输入错误!!!\n");
		}
	} while (server1 != 'A'&& server1 != 'B'&& server1 != 'C');
	return 0;
}

/*返回选项
*/
int  Return_operation()
{
	char i;
	printf("*********** 1.返回主菜单\n");
	printf("*********** 2.结束\n");
	do
	{
		printf("# 请 输 入 你 的 选 项 # :");
		i = getchar();                        //清楚字符缓存区,只让getchar识别第一个字符
		get_only_oneworld();
		switch (i)
		{
		case '1':Main_menu(); break;
		case '2':break;
		default:printf("输入错误!!!\n");
		}
	} while (i != '1' && i != '2');
	return 0;
}

// 显示图书菜单
void all_book(struct book_date *head)
{
	L = head;
	void  Statistical_books(struct book_date *);              //统计图书馆书籍(借出和库存)
	system("cls");
	printf("* * * * * * * * 书籍目录 * * * * * * * *\n\n");
	Statistical_books(L);
	printf(" (A) 显 示 借 出 书 籍\n");
	printf(" (B) 显 示 库 存 书 籍\n");
	printf(" (C) 预 览 图 书\n");
	printf(" (D) 返 回 上 一 步\n");
	printf("* * * * * * * * * * * * * * * * * * * *\n");
	char server;
	do
	{
		printf("# 请 输 入 您 的 选 项 # :");
		server = getchar();
		get_only_oneworld();
		switch (server)
		{
		case 'A': lend_book(L); break;                  
		case 'B': now_book(L); break;                    
		case 'C':  put_date(L); break;                     
		case 'D': Main_menu(); break;                   
		default:printf("输入错误!!!\n");
		}
	} while (server != 'D');
}

 

你可能感兴趣的:(C/C++)