大家好!今天和大家分享的案例是用C++写一个图书管理系统。前面和大家分享了用C++写一个学生成绩管理系统,与这个系统不同的是,我们今天使用另外一种结构体写法,也增加了数据读取和写入的模块,解决数据保存和初始化的问题,实现数据持久化。今天我使用的是DevC++,上次有粉丝说VC6.0有点老,其实使用习惯问题,有些老项目维护还是VC6.0,大家也可以使用其他IDE,对代码本身没太大影响。
需求:
-
有总界面指引目录,方便用户了解使用功能。
-
能查询所有图书信息。
-
能添加一本新图书。
-
能查询系统存在的图书,不存在的话给出指引。
-
能删除系统存在的图书,不存在的话给出指引。
-
能修改系统存在的图书,不存在的话给出指引。
- 能清空整个书库。
- 能实现读取文件数据和把修改过的数据写回文件保存。
-
能退出系统。
总目录界面如下:

编写过程:
1、导入所需的头文件
2、使用命名空间、定义结构体Person作为书的主体,结构体中包含string型name存放书名,int型price存放书的价格,string型number存放书的编号。定义结构体Arraybooks作为书库主体,里面两个成员,一个是Person结构体类型的book数组,用于存放书列表,一个是int型length,记录书库记录条数。
using namespace std;struct Person {string name;int price;string number;};struct Arraybooks {struct Person book[MAX];int length;};
3、定义文件数据读取函数,利用fopen方法打开文件,使用fscanf函数实现切分读取,并赋值给传指针进来的abs书库,实现数据读取和系统数据初始化。
int read_data(Arraybooks* abs){FILE *fp;fp=fopen("./bookList.txt","r");if(fp==NULL){cout<<"文件打开失败!"<<endl;exit(1);return 0;}while(1){if(feof(fp))break;char temp_name[30],temp_number[10];int temp_price;fscanf(fp,"%st%dt%sn",&temp_name,&temp_price,&temp_number);abs->book[abs->length].name=temp_name;abs->book[abs->length].price=temp_price;abs->book[abs->length].number=temp_number;abs->length++;}fclose(fp);return abs->length;}
4.定义数据写入文件函数,把系统修改过的数据写入到文件,实现数据持久化。
void write_data(Arraybooks* abs){std::ofstream file("./bookList.txt"); // 创建输出文件流对象if (file.is_open()){ // 确保文件成功打开for(int i=0;i<abs->length;i++){file << abs->book[i].name <<"t"<< abs->book[i].price<<"t"<<abs->book[i].number<<"n"; // 将字符串写入文件}file.close(); // 关闭文件流//std::cout << "写入成功!" << std::endl;}else {std::cerr << "无法打开文件!" << std::endl;}}
5.定义添加数据函数,实现把数据添加到书库。
void addBooks(Arraybooks* abs) {if (abs->length >= MAX) {cout << "书籍已满" << endl;}else {string name;cout << "请输入书籍的名字: " << endl;cin >> name;abs->book[abs->length].name = name;int price;cout << "请输入书的价格:" << endl;cin >> price;abs->book[abs->length].price = price;string num;cout << "请输入书的编号:" << endl;cin >> num;abs->book[abs->length].number = num;abs->length++;cout << "添加成功" << endl;}}
6.定义查询书名是否存在函数,查到返回数据位置,查不到返回-1。
int isExist(Arraybooks* abs, string name) {for (int i = 0; i < abs->length; ++i) {if (abs->book[i].name == name) {return i;}}return -1;}
7.定义删除图书信息函数,存在则删除并移动数据,不存在则提示查无此书
void dalateBooks(Arraybooks* abs) {cout << "请输入你要删除的书籍" << endl;string name;cin >> name;int ret = isExist(abs, name);if (ret != -1 && ret != abs->length - 1) {abs->book[ret].name = abs->book[ret + 1].name;abs->book[ret].number = abs->book[ret + 1].number;abs->book[ret].price = abs->book[ret + 1].price;for (int i = ret + 1; i < abs->length; ++i) {abs->book[i].name = abs->book[i+1].name;abs->book[i].number = abs->book[i+1].number;abs->book[i].price = abs->book[i+1].price;}abs->length--;cout << "删除成功" << endl;}else if(ret != 1 && ret == abs->length - 1) {abs->length--;}else {cout << "查无此书" << endl;}}
8.定义查询某本书信息函数,查到则给出图书的详细信息,查不到则提示查无此书。
void CheckBook(Arraybooks* abs) {cout << "输入你要查找的书籍" << endl;string name;cin >> name;int ret = isExist(abs, name);if (ret != -1) {cout << "书名为:" << abs->book[ret].name << "t";cout << "书价格为:" << abs->book[ret].price << "t";cout << "书编号为:" << abs->book[ret].number << endl;}else {cout << "查无此书" << endl;}}
9.定义清空书库函数,实现一次性清空书库操作。
void cleanbooks(Arraybooks* abs) {abs->length = 0;cout << "清理完成" << endl;}
10、定义某本图书信息函数,存在则提供修改提示,不存在则提示查无此书。
void changebooks(Arraybooks* abs) {cout << "输入你要修改的图书" << endl;string name;cin >> name;int ret = isExist(abs, name);if (ret != -1) {cout << "请输入名字:" << endl;string name;cin >> name;abs->book[ret].name = name;cout << "请输入价格:" << endl;int price;cin >> price;abs->book[ret].price = price;cout << "请输入编号: " << endl;string num;cin >> num;abs->book[ret].number = num;}else {cout << "查无此书" << endl;}}
11、定义显示所有书库信息函数,实现打印整个书库所有书籍详细信息。
void showbooks(Arraybooks* abs) {if (abs->length == 0) {cout << "书架为空" << endl;}else {for (int i = 0; i < abs->length; ++i) {cout << "书籍名字 :" << abs->book[i].name << "t";cout << "书籍价格 :" << abs->book[i].price << "t";cout << "书籍编号 :" << abs->book[i].number << endl;}}}
12、定义退出系统界面提示函数
int outSystem() {cout << "欢迎下次使用" << endl;return 0;}
13.定义软件使用提示界面函数
void mean() {cout << "**************************" << endl;cout << "*******1、加入图书********" << endl; //OKcout << "*******2、按名删除图书****" << endl;//OKcout << "*******3、按名查找图书****" << endl;//OKcout << "*******4、清空图书架******" << endl;//OKcout << "*******5、修改图书名******" << endl;cout << "*******6、显示图书架******" << endl;//OKcout << "*******0、退出系统********" << endl; //OKcout << "**************************" << endl;}
14、编写主函数,在主函数中按需要调用前面定义好的函数
int main() {int x;Arraybooks abs;abs.length = 0;read_data(&abs);while (true) {mean();cout<<"请输入操作号:"<<endl;cin >> x;switch (x) {case 1:addBooks(&abs);write_data(&abs);break;case 2:dalateBooks(&abs);write_data(&abs);break;case 3:CheckBook(&abs);break;case 4:cleanbooks(&abs);write_data(&abs);break;case 5:changebooks(&abs);write_data(&abs);break;case 6:showbooks(&abs);break;case 0:outSystem();write_data(&abs);break;}if (x==0){system("pause");break;}}return 0;}
操作效果演示:



