cc++结构体练手小案例(简化版图书管理系统)

cc++结构体练手小案例(简化版图书管理系统),第1张

前言

前不久看了B站黑马教程的通讯管理系统,正好Java老师让我们做一个图书管理的小demo,尝试用c++(其实不算是,主要思想还是面向过程)实现一下吧,可以练习一下结构体的使用。语言表达有限望理解。

 具体实现 结构体设计

做这个案例首先要设计足够好的结构体,就像打地基一样,如果地基打的乱七八糟,想必你写到一半就会写不下去或者代码到处出错崩溃掉。

我的结构体主要是三个部分:

首先是一个图书列表的结构体,该结构体包含一个图书列表的数组和记录该数组长度(一共有多少种书)的size。

其次是一个图书的结构体,包含图书的名称,作者,编号,以及该书的数量。下来是一个记录该书的借阅名单的数组及借阅的人数p_size。

最后是一个人员的结构体,包含两个内容,人员名称和借出该书的本数。

如果还比较蒙圈,可以看一下下边的绘图,可以一目了然了。

#define MAX 100

struct person {
	string p_name;
    //这个人借了多少本
	int borrowCount;
};

struct book {
	string name;
	string author;
    //编号
	string num;
	int count;
    //谁借了这本书
	struct person personArray[MAX];
	int p_size;
};

struct bookList {
    //都有哪些书
	struct book bookArray[MAX];
	int size;
};

 

main()函数实现

首先简单敲一个菜单。

main()部分,创建一个bookList结构体变量bl,初始化书本列表为0。

接下来就是展示菜单,收集用户输入的选项,根据用户输入,跳转到不同功能函数的入口。这部分用一个死循环while(true){}包裹起来。因为我们不能只允许用户输入一次选项就让整个程序跑完,这肯定是不合理的。但什么时候跳出这个循环让程序结束,设置case 0 退出的选项,直接return 0;程序结束。如果用户输入非法的选项,我们也要提醒一下让重新输入。

//显示菜单
void showMenu() {
	cout << "********************" << endl;
	cout << "**** 1.添加图书 ****" << endl;
	cout << "**** 2.图书列表 ****" << endl;
	cout << "**** 3.查找图书 ****" << endl;
	cout << "**** 4.借阅图书 ****" << endl;
	cout << "**** 5.归还图书 ****" << endl;
	cout << "**** 6.删除图书 ****" << endl;
	cout << "**** 0.退出系统 ****" << endl;
	cout << "********************" << endl;
}
int main() {
	//初始化一个图书列表
	bookList bl;
	bl.size = 0;
	//用户输入的选项
	int select = 0;

	while (true) {
        //展示菜单
		showMenu();
		cout << "请输入您的选项" << endl;
		cin >> select;
		switch (select)
		{
		case 1:
            //添加图书
			addBook(&bl);
			break;
		case 2:
            //展示所有图书列表
			showBook(&bl);
			break;
		case 3:
            //查找某一本图书
			findBook(&bl);
			break;
		case 4:
            //借阅图书
			borrowBook(&bl);
			break;
		case 5:
            //返还图书
			returnBook(&bl);
			break;
		case 6:
            //删除某一个图书
			deleteBook(&bl);
			break;
		case 0:
		{
			system("pause");
			return 0;
		}
		break;
		default:
			cout << "输入有误,重新输入" << endl;
			system("pause");
			system("cls");
			break;
		}
	}

	system("pause");
	return 0;
}
添加图书函数实现

效果展示

 

我们要传入刚开始创建的结构体变量bl。其他的函数也类似,我们的所有 *** 作都基于这个结构体变量bl,都是在增删改查这个bl里的数据。

做这个函数之前,我们先实现一个用于判断图书馆列表中有没有某种书的函数,如果有就返回这个书籍在bookArray里的下标,如果没有返回-1。。为什么要做这个函数,如果你要添加这本书本来图书馆就有了,那么你如果只是做一个简单的追加在bookArray结尾,是不是会出现书籍重复的现象。所以我们要先把bookArray过滤一遍,如果要添加的书本来就有了,则提醒用户"该书已存在,请输入要增添的本数",然后修改count即可。这个函数用一个for循环即可,循环次数正好pbl->size次,逐一检查我们已经添加书籍中有没有名字和参数传入的名字相等的。

函数结果用flag接收一下,如果flag值为-1,说明图书馆里没有这本书,则我们在bookArray这个数组后面追这个新的书,让用户依次输入这本书的信息,同时初始化该书借阅列表personArray的长度即p_size为0。这里有一个小技巧,pbl->size本来是记录图书列表bookArray数组的长度,但是同时也是bookArray这个数组最后一个元素再往后一个元素的下标,这让我们的 *** 作就很方便了。添加后记得让pbl->size++。

如果flag值不为-1,则是这本书在图书列表bookArray中的下标。我们需要用户输入增添几本,并把这本书的数量修改一下即可,这里就不用pbl->size++,因为我们没有添加新的书籍,这本书本来就存在了。

最后有一个小 *** 作,system("pause")这是把终端清屏,然后输出这次 *** 作的结果,“添加成功”。程序继续往下走回到main函数,继续输出菜单让用户进行下次 *** 作。。这样做既不会在终端上一直显示历史 *** 作而显得冗余,同时又把此次 *** 作的结果输出在了终端的最上方,并时刻保持终端上留有菜单不会被清掉,以此达到最佳的交互效果。。

//检索图书是否存在并返回下标
int isExist(struct bookList* pbl, string name) {
	for (int i = 0; i <= pbl->size; i++) {
		if (pbl->bookArray[i].name == name)
			return i;
	}
	return -1;
}
//添加图书的函数
void addBook(struct bookList* pbl) {
	cout << "请输入图书的名字" << endl;
	string name;
	cin >> name;
	int flag = isExist(pbl, name);
	if (flag == -1) {
		pbl->bookArray[pbl->size].name = name;
		cout << "请输入图书的作者" << endl;
		string author;
		cin >> author;
		pbl->bookArray[pbl->size].author = author;
		cout << "请输入图书的编号" << endl;
		string num;
		cin >> num;
		pbl->bookArray[pbl->size].num = num;
		cout << "请输入图书的本数" << endl;
		int count;
		cin >> count;
		pbl->bookArray[pbl->size].count = count;
		//初始化该图书借阅人数为0
		pbl->bookArray[pbl->size].p_size = 0;
		//图书种类加一
		pbl->size++;
	}
	else {
		cout << "该书已存在,请输入要增添的本数" << endl;
		int addCount;
		cin >> addCount;
		pbl->bookArray[flag].count += addCount;
	}
	system("cls");
	cout << "添加成功" << endl;
}
展示图书列表函数实现

效果展示

 

这个就很简单了,一个for循环遍历一下bookArray数组,并展示信息。前面已经提到了pbl->size是整个图书列表有几种书(不是几本书,我们每一种书的本数可能不止一本)。

//展示图书列表
void showBook(struct bookList* pbl) {
	system("cls");
	for (int i = 0; i < pbl->size; i++) {
		cout << "图书名称:" << pbl->bookArray[i].name << "\t";
		cout << "图书作者:" << pbl->bookArray[i].author << "\t";
		cout << "图书编号:" << pbl->bookArray[i].num << "\t";
		cout << "图书数量:" << pbl->bookArray[i].count << "\t";
		cout << endl;
	}
}
查找某一本书函数实现

效果展示

 

为了保证我们的查找结果输出在屏幕最上方。在输入要查找的图书名称后又做了一次清屏哈。

这里就用到了上边已经实现过的查找某本图书的函数了。

如果flag值为-1,则没有这本书,输出“图书馆暂无此书”

如果flag值返回的不是-1,而是要找的这本书在bookArray里的下标。则就要输出找到的这本书的信息了,依次输出即可。

因为书这个结构体里包含了一个借阅人员列表的数组,所以我们需要把这个数组也遍历一下并输出。是不是比较复杂了?bookList结构体里套bookArray数组,数组里是book结构体,book结构体里继续套personArray数组,数组元素是一个person结构体。有点迷糊的话再看一下文章开始画的图吧。                               输出这个借阅人员列表也比较简单,这个名单的长度我们有记录,就是book结构体里有一个成员变量p_size。每个人借阅了几本我们也记录了,就是person结构体里的成员变量borrowCount。

//查找图书
void findBook(struct bookList* pbl) {
	cout << "请输入你要查找的图书名称" << endl;
	string name;
	cin >> name;
	system("cls");
	int flag = isExist(pbl, name);
	if (flag == -1)
		cout << "图书馆暂无此书" << endl;
	else {
		cout << "图书名称:" << pbl->bookArray[flag].name << "\t";
		cout << "图书作者:" << pbl->bookArray[flag].author << "\t";
		cout << "图书编号:" << pbl->bookArray[flag].num << "\t";
		cout << "图书数量:" << pbl->bookArray[flag].count << endl;
		cout << "借阅名单:" << endl;
		for (int i = 0; i < pbl->bookArray[flag].p_size; i++) {
			cout << pbl->bookArray[flag].personArray[i].p_name << "\t";
			cout << pbl->bookArray[flag].personArray[i].borrowCount<<"本" << endl;
		}
	}
}
借阅图书函数实现

难点要来了,首先我们每一本书都有记录的借阅成员列表personList,所以在借阅某一本书时,你要让用户输入他的名字,要接哪本书,借几本?

借之前,我们要判断图书列表bookArray里有没有用户要的这本书。没有则输出“借阅失败,图书馆查无此书”,那么该函数直接执行完毕并 退出。

如果图书馆有这本书,我们要判断一下用户借的本数和我们图书馆该书剩余这本数的大小关系,如果用户借的数量大于了图书馆该书剩余数量,则输出借阅失败,该图书仅剩X本。

如果以上两步都没有问题,则进入到借书的关键步骤。和添加图书一样的问题,如果一个人张三已经借过该书,在借阅名单上已经有张三的借阅记录了,那么我们还能在这个personArray列表后面直接追加一个新的张三吗?是不是重复了,所以我们要先遍历一下personArray,看目前要借书的这个人是不是已经在personArray里边了。如果已经在里边了,则只需要增加一下borrowCount这个数值即可,记得要把这本书在图书馆里的数量count 减去借阅的数量,一定要记得。

如果以上遍历没有找到张三,则张三之前没有借过这本书,因此要在personArray列表里追加一个新的借阅人的信息。一定要记得book结构体里有一个p_size要+1。同样把这本书在图书馆里的数量count 减去借阅的数量。

//借阅图书
void borrowBook(struct bookList* pbl) {
	cout << "请输入你的名字" << endl;
	string p_name;
	cin >> p_name;
	cout << "请输入要借阅的图书" << endl;
	string name;
	cin >> name;
	int flag = isExist(pbl, name);
    //图书馆是否有这本书
	if (flag == -1) {
		system("cls");
		cout << "借阅失败,图书馆查无此书" << endl;
		return;
	}

    //借阅的数量是不是比这本图书剩余的数量还要大?
	cout << "请输入要借阅的数量" << endl;
	int count;
	cin >> count;
	if (count > pbl->bookArray[flag].count) {
		system("cls");
		cout << "借阅失败,图书馆该书仅剩余" << pbl->bookArray[flag].count <<"本" << endl;
		return;
	}

	for (int i = 0; i < pbl->bookArray[flag].p_size; i++) {
		if (pbl->bookArray[flag].personArray[i].p_name == p_name) {
			pbl->bookArray[flag].personArray[i].borrowCount += count;
	
			pbl->bookArray[flag].count -= count;

			system("cls");
			cout << "借阅成功" << endl;
			return;
		}
	}
	pbl->bookArray[flag].personArray[pbl->bookArray[flag].p_size].p_name = p_name;
	pbl->bookArray[flag].personArray[pbl->bookArray[flag].p_size].borrowCount = count;
	pbl->bookArray[flag].p_size++;
	pbl->bookArray[flag].count -= count;

	system("cls");
	cout << "借阅成功" << endl;
}
归还图书函数实现

归还图书的逻辑稍显复杂,一定要对前面定义的结构体有熟练的把握。

归还分两种情况,一种是归还的数量小于已经借阅的数量,比如张三接了《单片机》三本,结果还了一本。第二种是全部还完,张三归还了自己借的全部三本。

首先要对personArray列表进行遍历找到张三这个人。判断张三要归还的数目和借的数目是否相等,相等的话就是上边说的第二种情况。把张三从personArray数组中删除,怎么删?从张三所在的下标开始,往后的元素均往前挪动一位,就把张三给覆盖掉了。如下图:。一定要记得要把记录借阅人员列表数组长度的p_size--。。pbl->bookArray[flag].p_size--。否则前边展示借阅名单的时候遍历就会出错了。

 

假如是第一种情况,张三没有全部还完,只还了一部分,那么就不能把张三这个人从personArray中删除。只用把借的书数量borrowCount减去归还的数量。同时把这本书在图书馆中的数量count加上归还的数量即可。

//归还图书
void returnBook(struct bookList* pbl) {
	cout << "请输入你的名字" << endl;
	string p_name;
	cin >> p_name;
	cout << "请输入要归还的图书" << endl;
	string name;
	cin >> name;
	cout << "请输入要归还的数量" << endl;
	int count;
	cin >> count;
	int flag = isExist(pbl, name);
	for (int i = 0; i < pbl->bookArray[flag].p_size; i++) {
        //从借阅名单中找到这个人
		if (pbl->bookArray[flag].personArray[i].p_name == p_name) {
            //如果归还的数量和借阅的数量相等,就把这个人从借阅名单中删除
			if (pbl->bookArray[flag].personArray[i].borrowCount == count) {
				for (int j = i; j < pbl->bookArray[flag].p_size; j++) {
					pbl->bookArray[flag].personArray[j] = pbl->bookArray[flag].personArray[j + 1];
				}
				pbl->bookArray[flag].p_size--;
			}
			else {
				pbl->bookArray[flag].personArray[i].borrowCount -= count;
			}
		}
	}
	pbl->bookArray[flag].count += count;
	system("cls");
	cout << "归还成功" << endl;
}
删除一个图书函数实现

这个就很简单了,首先还是判断一下图书馆有没有这本书,没有返回查无此书

如果有的话就把这本书从图书列表bookArray中删除,删除的 *** 作和上面删除一个人的 *** 作是一样的,让数组中从这个元素往后的元素,都往前移一位即可。记得要pbl->size--,很重要。

//删除图书
void deleteBook(struct bookList* pbl) {
	cout << "请给出删除图书的名称" << endl;
	string name;
	cin >> name;
	int flag = isExist(pbl, name);
	if (flag == -1) {
		system("cls");
		cout << "查无此书" << endl;
		return;
	}
	for (int i = flag; i < pbl->size; i++) {
		pbl->bookArray[i] = pbl->bookArray[i + 1];
	}
	pbl->size--;
	system("cls");
	cout << "删除成功" << endl;
}
全部代码
#include 
#include ;
using namespace std;
#define MAX 100

struct person {
	string p_name;
	int borrowCount;
};

struct book {
	string name;
	string author;
	string num;
	int count;
	struct person personArray[100];
	int p_size;
};

struct bookList {
	struct book bookArray[MAX];
	int size;
};


//显示菜单
void showMenu() {
	cout << "********************" << endl;
	cout << "**** 1.添加图书 ****" << endl;
	cout << "**** 2.图书列表 ****" << endl;
	cout << "**** 3.查找图书 ****" << endl;
	cout << "**** 4.借阅图书 ****" << endl;
	cout << "**** 5.归还图书 ****" << endl;
	cout << "**** 6.删除图书 ****" << endl;
	cout << "**** 0.退出系统 ****" << endl;
	cout << "********************" << endl;
}

//检索图书是否存在并返回下标
int isExist(struct bookList* pbl, string name) {
	for (int i = 0; i <= pbl->size; i++) {
		if (pbl->bookArray[i].name == name)
			return i;
	}
	return -1;
}

//添加图书的函数
void addBook(struct bookList* pbl) {
	cout << "请输入图书的名字" << endl;
	string name;
	cin >> name;
	int flag = isExist(pbl, name);
	if (flag == -1) {
		pbl->bookArray[pbl->size].name = name;
		cout << "请输入图书的作者" << endl;
		string author;
		cin >> author;
		pbl->bookArray[pbl->size].author = author;
		cout << "请输入图书的编号" << endl;
		string num;
		cin >> num;
		pbl->bookArray[pbl->size].num = num;
		cout << "请输入图书的本数" << endl;
		int count;
		cin >> count;
		pbl->bookArray[pbl->size].count = count;
		//初始化该图书借阅人数为0
		pbl->bookArray[pbl->size].p_size = 0;
		//图书种类加一
		pbl->size++;
	}
	else {
		cout << "该书已存在,请输入要增添的本数" << endl;
		int addCount;
		cin >> addCount;
		pbl->bookArray[flag].count += addCount;
	}
	system("cls");
	cout << "添加成功" << endl;
}

//展示图书列表
void showBook(struct bookList* pbl) {
	system("cls");
	for (int i = 0; i < pbl->size; i++) {
		cout << "图书名称:" << pbl->bookArray[i].name << "\t";
		cout << "图书作者:" << pbl->bookArray[i].author << "\t";
		cout << "图书编号:" << pbl->bookArray[i].num << "\t";
		cout << "图书数量:" << pbl->bookArray[i].count << "\t";
		cout << endl;
	}
}

//查找图书
void findBook(struct bookList* pbl) {
	cout << "请输入你要查找的图书名称" << endl;
	string name;
	cin >> name;
	system("cls");
	int flag = isExist(pbl, name);
	if (flag == -1)
		cout << "图书馆暂无此书" << endl;
	else {
		cout << "图书名称:" << pbl->bookArray[flag].name << "\t";
		cout << "图书作者:" << pbl->bookArray[flag].author << "\t";
		cout << "图书编号:" << pbl->bookArray[flag].num << "\t";
		cout << "图书数量:" << pbl->bookArray[flag].count << endl;
		cout << "借阅名单:" << endl;
		for (int i = 0; i < pbl->bookArray[flag].p_size; i++) {
			cout << pbl->bookArray[flag].personArray[i].p_name << "\t";
			cout << pbl->bookArray[flag].personArray[i].borrowCount<<"本" << endl;
		}
	}
}

//借阅图书
void borrowBook(struct bookList* pbl) {
	cout << "请输入你的名字" << endl;
	string p_name;
	cin >> p_name;
	cout << "请输入要借阅的图书" << endl;
	string name;
	cin >> name;
	int flag = isExist(pbl, name);
	if (flag == -1) {
		system("cls");
		cout << "查无此书" << endl;
		return;
	}
	cout << "请输入要借阅的数量" << endl;
	int count;
	cin >> count;
	if (count > pbl->bookArray[flag].count) {
		system("cls");
		cout << "借阅失败,图书馆该书仅剩余" << pbl->bookArray[flag].count <<"本" << endl;
		return;
	}

	for (int i = 0; i < pbl->bookArray[flag].p_size; i++) {
		if (pbl->bookArray[flag].personArray[i].p_name == p_name) {
			pbl->bookArray[flag].personArray[i].borrowCount += count;
	
			pbl->bookArray[flag].count -= count;

			system("cls");
			cout << "借阅成功" << endl;
			return;
		}
	}
	pbl->bookArray[flag].personArray[pbl->bookArray[flag].p_size].p_name = p_name;
	pbl->bookArray[flag].personArray[pbl->bookArray[flag].p_size].borrowCount = count;
	pbl->bookArray[flag].p_size++;
	pbl->bookArray[flag].count -= count;

	system("cls");
	cout << "借阅成功" << endl;
}


//归还图书
void returnBook(struct bookList* pbl) {
	cout << "请输入你的名字" << endl;
	string p_name;
	cin >> p_name;
	cout << "请输入要归还的图书" << endl;
	string name;
	cin >> name;
	cout << "请输入要归还的数量" << endl;
	int count;
	cin >> count;
	int flag = isExist(pbl, name);
	for (int i = 0; i < pbl->bookArray[flag].p_size; i++) {
		if (pbl->bookArray[flag].personArray[i].p_name == p_name) {
			if (pbl->bookArray[flag].personArray[i].borrowCount == count) {
				for (int j = i; j < pbl->bookArray[flag].p_size; j++) {
					pbl->bookArray[flag].personArray[j] = pbl->bookArray[flag].personArray[j + 1];
				}
				pbl->bookArray[flag].p_size--;
			}
			else {
				pbl->bookArray[flag].personArray[i].borrowCount -= count;
			}
		}
	}
	pbl->bookArray[flag].count += count;
	system("cls");
	cout << "归还成功" << endl;
}

//删除图书
void deleteBook(struct bookList* pbl) {
	cout << "请给出删除图书的名称" << endl;
	string name;
	cin >> name;
	int flag = isExist(pbl, name);
	if (flag == -1) {
		system("cls");
		cout << "查无此书" << endl;
		return;
	}
	for (int i = flag; i < pbl->size; i++) {
		pbl->bookArray[i] = pbl->bookArray[i + 1];
	}
	pbl->size--;
	system("cls");
	cout << "删除成功" << endl;
}

int main() {
	//初始化一个图书列表
	bookList bl;
	bl.size = 0;
	//用户输入的选项
	int select = 0;

	while (true) {
		showMenu();
		cout << "请输入您的选项" << endl;
		cin >> select;
		switch (select)
		{
		case 1:
			addBook(&bl);
			break;
		case 2:
			showBook(&bl);
			break;
		case 3:
			findBook(&bl);
			break;
		case 4:
			borrowBook(&bl);
			break;
		case 5:
			returnBook(&bl);
			break;
		case 6:
			deleteBook(&bl);
			break;
		case 0:
		{
			system("pause");
			return 0;
		}
		break;
		default:
			cout << "输入有误,重新输入" << endl;
			system("pause");
			system("cls");
			break;
		}
	}

	system("pause");
	return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/3002946.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-27
下一篇 2022-09-27

发表评论

登录后才能评论

评论列表(0条)

保存