作业(四):图书管理系统

图书管理系统

导读:图书管理系统基于单链表与文件交互操作,这里我就做一个较为简单的图书管理交互,即图书数量为一。

功能如下:

  • 图书录入:头插法新增信息,这里设置ISBN值为唯一值,如重复则重新输入ISBN值
  • 图书显示:这里全部显示、通过书号查询
  • 图书修改:这里通过ISBN值进行查询是否存在
  • 学生借书:输入学生学号,输入书籍ID,如已借则无法借出,如在图书馆则可以借出
  • 学生还书:与借书情况相反

功能导图:
在这里插入图片描述代码解析:
1、头文件引入

#include <stdio.h> 
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#define NAME_LEN 20
#define FILE_NAME "图书管理系统.txt"

2、结构体信息

typedef struct {
	int ISBN;						//书籍编码 
	int money;						//价格 
	int student;		//学生学号 
	char bookname[NAME_LEN + 1];	//书籍名称 
	char bookwrite[NAME_LEN + 1];	//书籍作者 
	char bookpress[NAME_LEN + 1];	//书籍出版社
	char bookcategory[NAME_LEN + 1];//书籍类科
	char bookloan[5];				//是否借出 
	
} Bookmanage;					//用于存储单个学生的信息

typedef struct node {
	Bookmanage book;		//数据域,存储图书信息
	struct node *next;		//指针域,指向下一个节点
} BookmanageNode;			//图书节点

typedef struct {
	BookmanageNode *head;	//头指针
	BookmanageNode *tail;	//尾指针
	int count;				//图书节点总数
} bookList;	

3、函数声明

void first_main();
void initialize(bookList *L);//初始化链表,创建头节点
void enter(bookList *L);		//录入链表
void display(bookList *L);	//输出链表
void find(bookList *L);		//查找某节点
void modify(bookList *L);	//修改某节点
void sort(bookList *L);		//降序重新建表并输出
void write(bookList *L);		//写入文件,边写边释放空间
void read(bookList *L);		//读取文件,边读边建表
void Books_Borrow(bookList *L);
void Books_Return(bookList *L);
int check(bookList *L);

4、创建头结点

void initialize(bookList *L) {
	//创建头节点
	BookmanageNode *b = (BookmanageNode *)malloc(sizeof(BookmanageNode));
	b->next = NULL;
	//初始化链表:
	//头尾指针均指向头节点,初始长度为零
	L->head = b;
	L->tail = b;
	L->count = 0;
}

。。。。。。
功能介绍
1、主页面
在这里插入图片描述2、录入
在这里插入图片描述。。。。。。
附上代码:

/*
	图书管理系统 
*/
#include <stdio.h> 
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#define NAME_LEN 20
#define FILE_NAME "图书管理系统.txt"

typedef struct {
	int ISBN;						//书籍编码 
	int money;						//价格 
	int student;		//学生学号 
	char bookname[NAME_LEN + 1];	//书籍名称 
	char bookwrite[NAME_LEN + 1];	//书籍作者 
	char bookpress[NAME_LEN + 1];	//书籍出版社
	char bookcategory[NAME_LEN + 1];//书籍类科
	char bookloan[5];				//是否借出 
	
} Bookmanage;					//用于存储单个学生的信息

typedef struct node {
	Bookmanage book;		//数据域,存储图书信息
	struct node *next;		//指针域,指向下一个节点
} BookmanageNode;			//图书节点

typedef struct {
	BookmanageNode *head;	//头指针
	BookmanageNode *tail;	//尾指针
	int count;				//图书节点总数
} bookList;					//图书链表

void first_main();
void initialize(bookList *L);//初始化链表,创建头节点
void enter(bookList *L);		//录入链表
void display(bookList *L);	//输出链表
void find(bookList *L);		//查找某节点
void modify(bookList *L);	//修改某节点
void sort(bookList *L);		//降序重新建表并输出
void write(bookList *L);		//写入文件,边写边释放空间
void read(bookList *L);		//读取文件,边读边建表
void Books_Borrow(bookList *L);
void Books_Return(bookList *L);
int check(bookList *L);

void first_main(){
	//互动界面
	printf("		**************图书信息管理系统**************\n");
	printf("		*  1.录入新的书籍信息                      *\n");
	printf("		*  2.按编码修改书籍信息                    *\n");
	printf("		*  3.按编码查询书籍信息                    *\n");
	printf("		*  4.输出全部书籍的信息                    *\n");
	printf("		*  5.学生借书                              *\n");
	printf("		*  6.学生还书                              *\n");
	printf("		*  0.退出并保存管理系统                    *\n");
	printf("		********************************************\n");
	printf("  	                                                \n");
}

int main() {
	//创建图书链表
	bookList *L = (bookList *)malloc(sizeof(bookList));
	//初始化图书链表
	initialize(L);
	//从文件里读取数据到链表
	read(L);
	//互动界面是用一个无限循环和一个switch写的
	while (1) {
		first_main();
		int select;
		printf("请输入您的选择: ");
		scanf("%d", &select);
		system("cls"); 
		switch (select) {
			case 1:
				enter(L);
				break;
			case 2:
				modify(L);
				break;
			case 3:
				find(L);
				break;
			case 4:
				display(L);
				break;
			case 5:
				Books_Borrow(L);
				break;
			case 6:
				Books_Return(L);
				break;
			case 0:
				write(L);
				free(L->head);	//头节点被销毁
				free(L);		//链表被销毁
				return 0;
			default:
				printf("%d是无效的数字,请重新输入!\n\n", select);
				break;
		}
	}
	return 0;
}
void initialize(bookList *L) {
	//创建头节点
	BookmanageNode *b = (BookmanageNode *)malloc(sizeof(BookmanageNode));
	b->next = NULL;
	//初始化链表:
	//头尾指针均指向头节点,初始长度为零
	L->head = b;
	L->tail = b;
	L->count = 0;
}
int check(bookList *L){//查询是否相同 
	int isbn;
	while(1){	
		int k = 0,flag = 1;
		int ISBN[NAME_LEN];
		printf("请输入书籍编码:");
		scanf("%d", &isbn);
		BookmanageNode *b;
		b = L->head;
		while (b->next) {
			b = b->next;
			ISBN[k++] = b->book.ISBN;
		} 
		for(int i=0;i<k;i++){
			if(ISBN[i] == isbn){
				flag = 0;
				break;
			}
		}
		if(L->count<1||flag == 1)break;
			printf("书籍编码已存在请重新输入!\n");
	}
	return isbn;
}
void enter(bookList *L) {
	int ISBN;
	//创建新节点
	BookmanageNode *b = (BookmanageNode *)malloc(sizeof(BookmanageNode));
	//键入信息并存到新节点中
	printf("请输入书籍名称:");
	scanf("%s", b->book.bookname);
	ISBN = check(L);
	b->book.ISBN = ISBN;
	printf("请输入书籍作者:");
	scanf("%s", b->book.bookwrite);
	printf("请输入书籍出版社:");
	scanf("%s", b->book.bookpress);
	printf("请输入书籍类科:");
	scanf("%s", b->book.bookcategory);
	printf("请输入书籍价格:");
	scanf("%d", &b->book.money);
	strcpy(b->book.bookloan,"可借");
	b->book.student = 0; 
	//若链表为空,将尾指针指向新节点
	if (L->head == L->tail) {
		L->tail = b;
	}
	//将新节点插进链表头部(头插法)
	b->next = L->head->next;
	L->head->next = b;
	L->count++;
	//输出互动信息
	printf("信息录入成功!\n\n");
}
void display(bookList *L) {
	printf("共有%d本图书数据:\n", L->count);
	printf("书名\t\t\t编码\t\t学生\t\t作者\t\t出版社\t\t类科\t价格\t是否借出\n");
	//创建一节点指针指向头节点
	BookmanageNode *b;
	b = L->head;
	//遍历链表输出
	while (b->next) {
		b = b->next;
		printf("%s", b->book.bookname);
		printf("\t\t%d", b->book.ISBN);	
		printf("\t\t%d", b->book.student);
		printf("\t\t%s", b->book.bookwrite);
		printf("\t\t%s", b->book.bookpress);
		printf("\t%s", b->book.bookcategory);
		printf("\t%d", b->book.money);
		printf("\t%s", b->book.bookloan);
		printf("\n");
	}
	printf("\n");
}
void find(bookList *L) {
	//让用户输入要查找的书籍 
	printf("请输入书籍编码:");
	int isbn;
	scanf("%d", &isbn);
	//遍历链表对比名字
	BookmanageNode *b = L->head->next;
	while (b) {
		//符合了就输出并结束函数
		if (b->book.ISBN == isbn) {
			printf("书名\t\t\t编码\t\t学生\t\t作者\t\t出版社\t\t类科\t价格\t是否借出\n");
			printf("%s", b->book.bookname);
			printf("\t\t%d", b->book.ISBN);
			printf("\t\t%d", b->book.student);
			printf("\t\t%s", b->book.bookwrite);
			printf("\t\t%s", b->book.bookpress);
			printf("\t%s", b->book.bookcategory);
			printf("\t%d", b->book.money);
			printf("\t%s", b->book.bookloan);
			printf("\n\n");
			return;
		}
		//名字不符合就下一个
		b = b->next;
	}
	//遍历完里都没找到这个名字
	printf("没找到这个%d的信息!\n\n", isbn);
}
void modify(bookList *L) {
	//让用户输入要修改的书籍
	printf("请输入书籍编码:");
	int isbn,ISBN;
	scanf("%d", &isbn);
	//遍历链表对比名字
	BookmanageNode *b = L->head->next;
	while (b) {
		//符合了就让用户重新键入并结束函数
		if (b->book.ISBN == isbn) {
			printf("请重新输入信息:\n");
			printf("请输入书籍名称:");
			scanf("%s", b->book.bookname);
			ISBN = check(L);
			b->book.ISBN = ISBN;
			printf("请输入书籍作者:");
			scanf("%s", b->book.bookwrite);
			printf("请输入书籍出版社:");
			scanf("%s", b->book.bookpress);
			printf("请输入书籍类科:");
			scanf("%s", b->book.bookcategory);
			printf("请输入书籍价格:");
			scanf("%d", &b->book.money);
			printf("请输入书籍是否借出:");
			scanf("%s", b->book.bookloan);
			printf("信息修改成功!\n\n");
			return;
		}
		//名字不符合就下一个
		b = b->next;
	}
	//遍历完里都没找到
	printf("没找到这个%d的信息!\n\n", isbn);
}
void Books_Borrow(bookList *L) {
	//学生借阅书籍 
	printf("请输入学号(7位以内):");
	int studentID; 
	int isbn; 
	scanf("%d", &studentID);
	printf("请输入书号:");
	scanf("%d",&isbn); 
	//遍历链表对比名字
	BookmanageNode *b = L->head->next;
	while (b) {
		//符合了就让用户重新键入并结束函数
		if (b->book.ISBN == isbn) { 
			if(strcmp(b->book.bookloan,"可借")==0) {
				b->book.student=studentID;
				strcpy(b->book.bookloan,"借出"); 
				printf("图书借出成功!\n");
			}
			else if(b->book.bookloan != "可借") {
				printf("图书借出失败!\n");
			}
			return;
		}
		//名字不符合就下一个
		b = b->next;
	}
	//遍历完里都没找到
	printf("没找到这个%d的信息!\n\n", isbn);
}

void Books_Return(bookList *L) {
	//学生借阅书籍 
	printf("请输入学号(7位以内):");
	int studentID; 
	int isbn; 
	scanf("%d", &studentID);
	printf("请输入书号:");
	scanf("%d",&isbn); 
	//遍历链表对比名字
	BookmanageNode *b = L->head->next;
	while (b) {
		//符合了就让用户重新键入并结束函数
		if (b->book.ISBN == isbn) { 
			if(strcmp(b->book.bookloan,"借出")==0) {
				b->book.student=studentID;
				strcpy(b->book.bookloan,"可借"); 
				printf("图书归还成功!\n");
			}
			else if(b->book.bookloan != "借出") {
				printf("图书归还失败!\n");
			}
			return;
		}
		//名字不符合就下一个
		b = b->next;
	}
	//遍历完里都没找到
	printf("没找到这个%d的信息!\n\n", isbn);
}

void write(bookList *L) {
	//打开文件流
	FILE *fp = fopen(FILE_NAME, "w");
	if (fp == NULL) {
		printf("文件%s打开失败\n", FILE_NAME);
		exit(EXIT_FAILURE);
	}
	//将学生节点总数输出在第一行
	fprintf(fp, "%d\n", L->count);
	//创建一节点指针指向头节点
	BookmanageNode *b;
	b = L->head->next;
	//遍历链表,一组数据作为一行输出
	while (b) {
		fprintf(fp, "%s ", b->book.bookname);
		fprintf(fp, "%d ", b->book.student);
		fprintf(fp, "%d ", b->book.ISBN);
		fprintf(fp, "%s ", b->book.bookwrite);
		fprintf(fp, "%s ", b->book.bookpress);
		fprintf(fp, "%s ", b->book.bookcategory);
		fprintf(fp, "%d ", b->book.money);
		fprintf(fp, "%s ", b->book.bookloan);
		fprintf(fp, "\n");
		//输出完成之后释放节点空间
		BookmanageNode *next = b->next;
		free(b);
		b = next;
	}
	//关闭文件流
	fclose(fp);
	//互动信息
	printf("数据已保存!谢谢使用,再见!\n");
}
void read(bookList *L) {
	//打开文件流
	FILE *fp = fopen(FILE_NAME, "r");
	if (fp == NULL) {
		printf("文件%s打开失败\n", FILE_NAME);
		printf("文件%s正在创建,请稍后\n", FILE_NAME);
		fp = fopen(FILE_NAME, "w");
		Sleep(1000);
		printf("文件%s创建成功\n", FILE_NAME); 
	} 
	//读取第一行的学生节点总数
	fscanf(fp, "%d", &L->count);
	//循环读取数据,循环次数为count
	for (int i = 1; i <= L->count; i++) {
		//创建新节点
		BookmanageNode *b = (BookmanageNode *)malloc(sizeof(BookmanageNode));
		//读取数据
		fscanf(fp, "%s ", b->book.bookname);
		fscanf(fp, "%d ", &b->book.student);
		fscanf(fp, "%d ", &b->book.ISBN);
		fscanf(fp, "%s ", b->book.bookwrite);
		fscanf(fp, "%s ", b->book.bookpress);
		fscanf(fp, "%s ", b->book.bookcategory);
		fscanf(fp, "%d ", &b->book.money);
		fscanf(fp, "%s ", b->book.bookloan);
		//将新节点插进链表尾部(尾插法)
		b->next = NULL;
		L->tail->next = b;
		L->tail = b;
	}
	//关闭文件流
	fclose(fp);
}

附:代码可能存在不完善,望各位大神给出意见。感谢

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不知名的MasaNvi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值