大家好!今天和大家分享的案例是用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; //OK
cout << "*******2、按名删除图书****" << endl;//OK
cout << "*******3、按名查找图书****" << endl;//OK
cout << "*******4、清空图书架******" << endl;//OK
cout << "*******5、修改图书名******" << endl;
cout << "*******6、显示图书架******" << endl;//OK
cout << "*******0、退出系统********" << endl; //OK
cout << "**************************" << 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;
}
操作效果演示: