基于文件流的图书管理系统(C/C++实现)

基于文件流的图书管理系统(C/C++实现)

在这里插入图片描述

一、项目背景

在日常的图书馆管理中,图书的管理往往需要涉及到对图书数据的增删查改(CRUD)操作。为了更好地管理图书信息,我们可以利用C++的文件流(fstream)功能,结合简单的结构体和菜单界面,实现一个图书管理系统。本文将详细介绍如何基于文件流实现一个图书管理系统,涵盖图书信息的增、删、改、查操作。

二、项目功能概述

本图书管理系统包括以下主要功能:

  1. 添加图书:用户可以输入图书信息,将图书数据保存到文件中。
  2. 删除图书:支持按图书编号或图书名称删除图书信息。
  3. 修改图书信息:用户可以修改已有图书的信息。
  4. 查询图书:支持按图书编号或名称查询图书信息。
  5. 显示图书列表:展示所有图书的信息。

三、代码剖析

0.实现大致的菜单界面 main(); choose();

//根据用户输入的功能码选择功能函数 
void choose(int input){
	system("cls");
	switch(input){
		case 1: 
		cout << "你选择了添加功能" << endl ; 
			add();
			break;
		case 2: 
		cout << "你选择了删除功能" << endl ; 
			del(); 
			break;
		case 3: 
		cout << "你选择了修改功能" << endl ; 
			modifyBook();
			break;
		case 4: 
		cout << "你选择了列表功能" << endl ; 
			list(); 
			break;
		case 5: 
		cout << "你选择了查询功能" << endl ; 
			searchBook();
			break;
		case 0:     //退出系统也会实现先暂停退出   希望将这个选项排除 
			//1.加判断if  
			//2.修改 break 为 return 
			cout << "退出系统" << endl ;
			return ;
		default:
			cout << "功能码错误" << endl; 
	}
    
   //不管执行什么方法,都会去执行 暂停 以及 清空 
	system("pause"); 
	system("cls");
}



int main(int argc, char** argv) {
	int input = 1;
	 while(input !=0){
	 	
		cout << "1.添加图书"<< endl; 
		cout << "2.删除图书"<< endl; 
		cout << "3.修改图书"<< endl; 
		cout << "4.图书列表"<< endl; 
		cout << "5.图书查询"<< endl;
		cout << "0.退出系统"<< endl;
		cout << "输入选择功能(0-5)"<< endl;
		//用户把输入的值赋值给input  input作为循环条件 
		// 
		cin >> input; 	
		choose (input);
	 	 
	 	
	 }
	
	return 0;
}

1.定义了一个结构体 封装图书信息 添加add() 和 列表list()

首先实现两个比较容易实现的功能 add() 和list()

#include <iostream>
#include <string>
#include<fstream>//引入文件流 

using namespace std;
 

//定义一个结构体用于封装图书信息
struct Book {
    int no;                // 编号
    string bookName;       // 书名
    string author;         // 作者
    string publisher;      // 出版社
    double price;          // 价格
    string category;       // 分类
  
}; 

void add(){
	Book book;
    //添加数据处理 
	book.no = inputNo();
	book.bookName = inputbookName(); 
    
	cout << "请输入图书的编号"<< endl;
	cin >> book.no;
	
	cout << "请输入图书的书名"<< endl;
	cin >>book.bookName;
	
	cout << "请输入图书的作者"<< endl;
	cin >> book.author; 
	
	cout << "请输入图书的出版社"<< endl;
	cin >> book.publisher;
	
	cout << "请输入图书的价格"<< endl;
	cin >> book.price;
	
	cout << "请输入图书的分类"<< endl;
 	cin >> book.category;
	//使用文件流 把数据写入文件中去长期保存 
	//默认以覆盖的形式去打开文件 
	//ios::app 用来设置追加模式 
	ofstream o("book.txt", ios::app);  //把图书信息保存到文件里去 
	o << book.no << " " << book.bookName << " " << book.author <<" "
	  << book.publisher << " " << book.price << " " << book.category <<endl; 
	  
	//关闭流文件 
	o.close(); 
	cout <<"添加成功" <<endl;
	//暂停控制台的执行 
//	system("pause"); 
//	system("cls");
}


//用来打印学生列表的函数 
void list(){
	// 从文件中读取数据打印到控制台
	ifstream in("Book.txt"); 
	Book book;
	cout <<"编号\t书名\t作者\t出版社\t价格\t分类" << endl;  
	//读取的顺序必须和写入顺序相同 
	while(in >> book.no >> book.bookName >> book.author >>book.publisher >> book.price >> book.category ){
		cout <<  book.no << "\t";  
		cout <<  book.bookName << "\t";  
		cout <<  book.author << "\t";  
		cout <<  book.publisher << "\t";  
		cout <<  book.price << "\t";  
		cout <<  book.category << endl;  
	}
 
}

2.数据处理

对于add(); 这里需要对数据的校验进行判断 需要在 add ();的前方定义 多个个方法 实现数据输入的处理

这里我尝试使用递归的形式去判断

1.处理图书的编号

int inputNo(){
    cout << "请输入图书编号(编号必须是7位数, 并且不可以重复)" << endl;
    int no;
    cin >> no;
    while(no <1000000 || 9999999){
        cout << "编号必须是7位数, 并且不可以重复"  << endl;
        return inputNo();//递归调用
    }
    return no;
    //校验图书编号是否重复
	ifstream in ("Book.txt");
	Book book;
	while(in >> book.no >> book.bookName >> book.author >>book.publisher >> book.price >> book.category){
		if(no == book.no){
			cout << "学号已经存在,请重新输入" << endl;
			return inputNo(); 
		}
	}

修改 add book.no = inputNo();

2.处理图书名字

//使用while判断逻辑 不用递归了
string inputbookName(){
	cout << "请输入图书的名称(名称必须1-20字)" <<endl;
    string bookName;
    cin >> bookName;
    while(bookName.size() < 1|| bookName.size() > 20){
    cout << "名字的长度必须是1-20位,请重新输入。" << endl;
    cin >> bookName;
    }
    return bookName;
}

处理

string author;         // 作者
string publisher;      // 出版社
double price;          // 价格
string category;       // 分类

3.判断作者的数据

//使用while判断逻辑 不用递归了
string inputAuthor(){
	cout << "请输入作者的名字(名称必须2-8位)" <<endl;
    string author;
    cin >> author;
    while(author.size() < 1|| author.size() > 20){
    cout << "名字的长度必须是1-20位,请重新输入。" << endl;
    cin >> author;
    }
    return author;
}

4.判断出版社

//使用while判断逻辑  
string inputPublisher(){
	cout << "请输入作者的名字(名称必须2-8位)" <<endl;
    string publisher;
    cin >> publisher;
    while(publisher.size() < 1|| publisher.size() > 20){
    cout << "出版社的长度必须是1-20位,请重新输入。" << endl;
    cin >> publisher;
    }
    return publisher;
}

5.判断价格

double inputPrice(){
    cout << "请输入图书价格(价格1 - 1000)" << endl;
    double price;
    cin >> price;
    while(price < 0 || price > 9999){
        cout << "编号必须是有效数字小于9999位数"  << endl;
        return inputPrice();//递归调用
    }
    return price;
}

double inputPrice(){
    cout << "请输入图书价格(价格1 - 1000)" << endl;
    double price;
    cin >> price;
    while(price < 0 || price > 9999){
        cout << "编号必须是有效数字小于9999位数"  << endl;
        cin >> price;
    }
    return price;
}

6.判断分类 只能是 文学 科学 自然 名著

//使用while判断逻辑 不用递归了
string inputCategory(){
	cout << "请输入图书的类别(文学 科学 自然  名著)" <<endl;
    string category;
    cin >>category;
    while(category !="文学" &&category !="科学" && category !="自然" && category !="名著"){
    cout << "图书的类别(文学 科学 自然  名著),请重新输入。" << endl;
    cin >> category;
    }
    return category;
}

3.实现删除功能del(); 抽象 delByNo(); 以及 delByName();

a. 将编号删除抽象出来单独实现void delByNo();

//根据编号删除  需要从文件删除
void delByNo(){
    cout << "输入需要删除图书的学生学号"<< endl;
    int no;
    cin >> no;
    
    ifstream in("book.txt");
    //泛型用来限制该对象只能存储学生类型的数据
	vector<Book> list; 
    Book book1;
    bool result = false; //判断是否删除成功
    //将数据存储到泛型,再到对象中book1
    while (in >> book1.no >> book1.bookName >> book1.author >>book1.publisher >> book1.price >> book1.category){
        if(book1.no == no){
       	continue;
	   }
        list.push_back(book1);
    }
    in.close();
    //把vector里的数据写入到文件里去,直接覆盖,
	ofstream o("Book.txt"); 
	//使用for循环读取vector数据,在写入 
	for(int i = 0; i<list.size(); i++){
		Book book = list[i];  //将这个写入文件  添加的那个使用过 
	//实现写入 
		o << book.no << " " << book.bookName << " " << book.author <<" "
	  << book.publisher << " " << book.price << " " << book.category <<endl; 
	} 
	//写完之后关闭 输入流
	o.close(); 
    
    //判断bool类型的结果
    if(result){
         cout << "输出成功" << endl;
    }else {
        cout << "输出失败" << endl;
    }
}
3.1修改过程
 这里的功能实现了全部读取全部输出,没有进行逻辑控制添加如下语句后可以实现 

if(book1.no == no){ continue; }

  • 由于cpp不支持删除某一行,需要一个额外的文件来辅助完成,使用一行一行的读取,把需要的读取到新文件里 最后把酒文件删除
    
  •  还可以使用覆盖的操作去间接的实现
    

这里需要引入一个动态数组vector

这个代码虽然可以运行但是,删除以后 知道是否删除成功 这里只要执行到了if语句里边就表示删除成功了

bool result = FALSE;

  //判断bool类型的结果
    if(result){
         cout << "输出成功" << endl;
    }else {
        cout << "输出失败" << endl;
    }

b. void delByName();

// 根据书名删除
void delByName()
{
	cout << "请输入需要删除的图书名称:" << endl;
	string bookName;
	cin >> bookName;

	ifstream in("book.txt");
	vector<Book> list;
	Book book1;
	 
    //记录本次删除的人数
    int count = 0;
    

	// 读取所有图书信息,跳过要删除的图书
	while (in >> book1.no >> book1.bookName >> book1.author >> book1.publisher >> book1.price >> book1.category)
	{
		if (book1.bookName == bookName)
		{
			count ++; // 找到要删除的图书
			continue;
		}
		list.push_back(book1);
	}
	in.close();

	// 将剩余图书信息重新写入文件
	ofstream o("book.txt");
	for (int i = 0; i < list.size(); i++)
	{
		Book book = list[i];
		o << book.no << " " << book.bookName << " " << book.author << " "
		  << book.publisher << " " << book.price << " " << book.category << endl;
	}
	o.close();

	if (count > 0)
	{
		cout << "删除成功,本次删除了" << count  << "本书" << endl;
	}
	else
	{
		cout << "未找到该书名的图书,删除失败" << endl;
	}
}

c. void del();

//删除 
void del() {
    int type;
    while (true) {
        cout << "选择删除方式 1.根据图书编号删除 2.根据图书书名删除" << endl;
        cin >> type;
        if (type == 1) {
            delByNo();
            break;
        } else if (type == 2) {
            delByName();
            break;
        } else {
            cout << "输入错误,请重新选择" << endl;
        }
    }
}

4.实现查询功能searchBook();

a. void searchByNo();

//根据编号查询    使用首先读取文件流  ifstream , 将文件的 内容读取出来  如果有相同的则 跳出循环
void searchByNo(){
    cout << "请输入要查询的图书编号"  << endl;
    int no;
    cin >> no;
    ifstream in ("Book.txt");
    Book book;
    bool result = false;
    while(in >> book.no >> book.bookName >> book.author >> book.publisher >> book.price >> book.category){
		if(no == book.no){
            result = true;
           // 打印表头
            cout << "\n编号\t书名\t作者\t出版社\t价格\t分类" << endl;
        	cout << book.no << "\t";
			cout << book.bookName << "\t";
			cout << book.author << "\t";
			cout << book.publisher << "\t";
			cout << book.price << "\t";
			cout << book.category << endl;
            break; //找到之后退出循环  由于编号不会重复
        }
       
		
    }
    //判断是否存在
    if(!result){
        cout << "该编号不存在" << endl;
    }
}

b. void searchByName();

//按书名查询
void searchByName(){
     cout << "请输入要查询的图书名字"  << endl;
    string bookName;
    cin >> bookName;
    ifstream in ("Book.txt");
    Book book;
    bool result = false;  
    while(in >> book.no >> book.bookName >> book.author >> book.publisher >> book.price >> book.category){
		if(bookName == book.bookName){
           // result = true;
            
            if(!result)
            // 打印表头
            	cout << "\n编号\t书名\t作者\t出版社\t价格\t分类" << endl;   
            
          	 
            /*这里的表头会多次输出,解决方法 
           			 1 放到循环外部  任何时候都会输出
                     2.将 result = true;	反倒后方		*/
        	cout << book.no << "\t";
			cout << book.bookName << "\t";
			cout << book.author << "\t";
			cout << book.publisher << "\t";
			cout << book.price << "\t";
			cout << book.category << endl;
             result = true;
            // break;//这里的书名可能会重复
        }
        
    }
     //判断是否存在
    if(!result){
        cout << "该图书不存在" << endl;
    }
}

c. void searchBook();

//这里同样抽象出两个功能   实现no  和bookName查找
void searchBook(){
	cout << " 请选择查询方式:" << endl;
    cout << "1. 按编号查询" << endl;
	cout << "2.按书名查询" << endl;
    
    int type;
    cin >> type;
    
    if(type == 1){
        searchByNo();
    }else if(type == 2){
       searchByName();
    }else{
        cout << "输入错误,请重新输入" << endl;
        searchBook();
    }
}

5.修改功能void modifyBook();

//修改后成功运行
void modifyBook() {
    cout << "请输入要修改的图书编号:" << endl;
    int no;
    cin >> no;
    ifstream in("book.txt");
    //泛型用来限制该对象只能存储学生类型的数据
    vector<Book> bookList; 
    Book book1;
    bool result = false; // 判断是否找到图书

    // 将文件数据读取到 bookList 中
    while (in >> book1.no >> book1.bookName >> book1.author >> book1.publisher >> book1.price >> book1.category) {
        bookList.push_back(book1);
    }
    in.close();
    
    // 遍历图书列表,查找需要修改的图书
    for (int i = 0; i < bookList.size(); i++) {
        Book& book2 = bookList[i];  // 使用引用来直接修改 bookList 中的数据
        
        // 判断图书编号是否匹配
        if (book2.no == no) {
            // 输出当前图书信息
            cout << "编号\t书名\t作者\t出版社\t价格\t分类" << endl;  
            cout <<  book2.no << "\t";  
            cout <<  book2.bookName << "\t";  
            cout <<  book2.author << "\t";  
            cout <<  book2.publisher << "\t";  
            cout <<  book2.price << "\t";  
            cout <<  book2.category << endl;

            // 修改数据
             //如果可以进入if则可以找到
             //添加数据处理 并输入
            result = true;
            book2.no = inputNo();
            book2.bookName = inputbookName();
            book2.author = inputAuthor();
            book2.publisher = inputPublisher();
            book2.price = inputPrice();
            book2.category = inputCategory();
            break;  // 找到并修改后退出循环
        }
    }

    // 如果没有找到该编号,输出提示信息
    if (!result) {
        cout << "该编号不存在" << endl;
    } else {
        // 将修改后的数据写回到文件   使用文件流  实现覆盖
        ofstream o("book.txt");  // 打开文件进行写入
        if (o.is_open()) {
            // 遍历修改后的 bookList 并写回文件
            for (int i = 0; i < bookList.size(); i++) {
                Book& book2 = bookList[i];
                o << book2.no << " " << book2.bookName << " " << book2.author << " "
                  << book2.publisher << " " << book2.price << " " << book2.category << endl;
            }
            o.close();  // 完成写入后关闭文件流
            cout << "修改成功" << endl;
        } else {
            cout << "文件写入失败!" << endl;
        }
    }
}

四、完整代码

    #include <iostream>
#include <string>
#include<fstream>//引入文件流 
#include<vector> //删除模块使用到 

using namespace std;

//定义一个结构体用于封装图书信息
struct Book {
    int no;                // 编号
    string bookName;       // 书名
    string author;         // 作者
    string publisher;      // 出版社
    double price;          // 价格
    string category;       // 分类
  
}; 


 
//用来获取输入的图书序号进行格式校验  递归 
int inputNo(){
    cout << "请输入图书编号(编号必须是7位数, 并且不可以重复)" << endl;
    int no;
    cin >> no;
    while (no < 1000000 || no > 9999999){
        cout << "编号必须是7位数, 并且不可以重复"  << endl;
        return inputNo();//递归调用
    }
    return no;
    //校验图书编号是否重复
	ifstream in ("Book.txt");
	Book book;
	while(in >> book.no >> book.bookName >> book.author >>book.publisher >> book.price >> book.category){
		if(no == book.no){
			cout << "学号已经存在,请重新输入" << endl;
			return inputNo(); 
		}
	}
    
}

//使用while判断逻辑 不用递归了
string inputbookName(){
	cout << "请输入图书的名称(名称必须1-20字)" <<endl;
    string bookName;
    cin >> bookName;
    while(bookName.size() < 1|| bookName.size() > 20){
    cout << "名字的长度必须是1-20位,请重新输入。" << endl; 
    cin >> bookName;
    }
    return bookName;
}

//使用while判断逻辑 不用递归了
string inputAuthor(){
	cout << "请输入作者的名字(名称必须2-8位)" <<endl;
    string author;
    cin >> author;
    while(author.size() < 1|| author.size() > 20){
    cout << "名字的长度必须是1-20位,请重新输入。" << endl;
    cin >> author;
    }
    return author;
}

//使用while判断逻辑  
string inputPublisher(){
	cout << "请输入作者的名字(名称必须2-8位)" <<endl;
    string publisher;
    cin >> publisher;
    while(publisher.size() < 1|| publisher.size() > 20){
    cout << "出版社的长度必须是1-20位,请重新输入。" << endl;
    cin >> publisher;
    }
    return publisher;
}

double inputPrice(){
    cout << "请输入图书价格(价格1 - 1000)" << endl;
    double price;
    cin >> price;
    while(price < 0 || price > 9999){
        cout << "编号必须是有效数字小于9999位数"  << endl;
        return inputPrice();//递归调用
    }
    return price;
}

//使用while判断逻辑 不用递归了
string inputCategory(){
	cout << "请输入图书的类别(文学 科学 自然  名著)" <<endl;
    string category;
    cin >>category;
    while(category !="文学" &&category !="科学" && category !="自然" && category !="名著"){
    cout << "图书的类别(文学 科学 自然  名著),请重新输入。" << endl;
    cin >> category;
    }
    return category;
}

void add(){
	Book book;
	 //添加数据处理 
	book.no = inputNo();
	book.bookName = inputbookName(); 
	book.author = inputAuthor();
	book.publisher =inputPublisher();
	book.price =  inputPrice();
	book.category = inputCategory();
//	cout << "请输入图书的编号"<< endl;
//	cin >> book.no;
//	
//	cout << "请输入图书的书名"<< endl;
//	cin >>book.bookName;
//	
//	cout << "请输入图书的作者"<< endl;
//	cin >> book.author; 
//	
//	cout << "请输入图书的出版社"<< endl;
//	cin >> book.publisher;
//	
//	cout << "请输入图书的价格"<< endl;
//	cin >> book.price;
//	
//	cout << "请输入图书的分类"<< endl;
// 	cin >> book.category;
	//使用文件流 把数据写入文件中去长期保存 
	//默认以覆盖的形式去打开文件 
	//ios::app 用来设置追加模式 
	ofstream o("book.txt", ios::app);  //把图书信息保存到文件里去 
	o << book.no << " " << book.bookName << " " << book.author <<" "
	  << book.publisher << " " << book.price << " " << book.category <<endl; 
	  
	//关闭流文件 
	o.close(); 
	cout <<"添加成功" <<endl;
	//暂停控制台的执行 
//	system("pause"); 
//	system("cls");
}
//用来打印学生列表的函数 
void list(){
	// 从文件中读取数据打印到控制台
	ifstream in("Book.txt"); 
	Book book;
	cout <<"编号\t书名\t作者\t出版社\t价格\t分类" << endl;  
	//读取的顺序必须和写入顺序相同 
	while(in >> book.no >> book.bookName >> book.author >>book.publisher >> book.price >> book.category ){
		cout <<  book.no << "\t";  
		cout <<  book.bookName << "\t";  
		cout <<  book.author << "\t";  
		cout <<  book.publisher << "\t";  
		cout <<  book.price << "\t";  
		cout <<  book.category << endl;  
	}
 
}


//根据编号删除  需要从文件删除
void delByNo(){
    cout << "输入需要删除图书的学生学号"<< endl;
    int no;
    cin >> no;
    
    ifstream in("book.txt");
    //泛型用来限制该对象只能存储学生类型的数据
	vector<Book> list; 
    Book book1;
    bool result = false; //判断是否删除成功
    //将数据存储到泛型,再到对象中book1
    while (in >> book1.no >> book1.bookName >> book1.author >>book1.publisher >> book1.price >> book1.category){
        if(book1.no == no){
         
       	continue;
	   }
        list.push_back(book1);
    }
    in.close();
    //把vector里的数据写入到文件里去,直接覆盖,
	ofstream o("Book.txt"); 
	//使用for循环读取vector数据,在写入 
	for(int i = 0; i<list.size(); i++){
		Book book = list[i];  //将这个写入文件  添加的那个使用过 
	//实现写入 
		o << book.no << " " << book.bookName << " " << book.author <<" "
	  << book.publisher << " " << book.price << " " << book.category <<endl; 
	} 
	//写完之后关闭 输入流
	o.close(); 
    
    //判断bool类型的结果
    if(result){
         cout << "输出成功" << endl;
    }else {
        cout << "输出失败" << endl;
    }
}

// 根据书名删除
// 根据书名删除
void delByName()
{
	cout << "请输入需要删除的图书名称:" << endl;
	string bookName;
	cin >> bookName;

	ifstream in("book.txt");
	vector<Book> list;
	Book book1;
	 
    //记录本次删除的人数
    int count = 0;
    

	// 读取所有图书信息,跳过要删除的图书
	while (in >> book1.no >> book1.bookName >> book1.author >> book1.publisher >> book1.price >> book1.category)
	{
		if (book1.bookName == bookName)
		{
			count ++; // 找到要删除的图书
			continue;
		}
		list.push_back(book1);
	}
	in.close();

	// 将剩余图书信息重新写入文件
	ofstream o("book.txt");
	for (int i = 0; i < list.size(); i++)
	{
		Book book = list[i];
		o << book.no << " " << book.bookName << " " << book.author << " "
		  << book.publisher << " " << book.price << " " << book.category << endl;
	}
	o.close();

	if (count > 0)
	{
		cout << "删除成功,本次删除了" << count  << "本书" << endl;
	}
	else
	{
		cout << "未找到该书名的图书,删除失败" << endl;
	}
}



//删除 
void del(){
	cout << "选择删除方式 1.根据图书编号删除 2.根据图书书名删除" <<endl; 
	int type;
	cin >> type;
	if(type == 1){	
		delByNo();
	}else if(type == 2){
		delByName();
	}else{
		cout << "输入错误" <<endl; 
		//递归调用
		del(); 
	}
} 

//根据编号查询 
void searchByNo(){
    cout << "请输入要查询的图书编号"  << endl;
    int no;
    cin >> no;
    ifstream in ("Book.txt");
    Book book;
    bool result = false;
    while(in >> book.no >> book.bookName >> book.author >> book.publisher >> book.price >> book.category){
		if(no == book.no){
            result = true;
           // 打印表头
            cout << "\n编号\t书名\t作者\t出版社\t价格\t分类" << endl;
        	cout << book.no << "\t";
			cout << book.bookName << "\t";
			cout << book.author << "\t";
			cout << book.publisher << "\t";
			cout << book.price << "\t";
			cout << book.category << endl;
            break; //找到之后退出循环  由于编号不会重复
        }
       
		
    }
    //判断是否存在
    if(!result){
        cout << "该编号不存在" << endl;
    }
}

//按书名查询
void searchByName(){
     cout << "请输入要查询的图书名字"  << endl;
    string bookName;
    cin >> bookName;
    ifstream in ("Book.txt");
    Book book;
    bool result = false;  
    while(in >> book.no >> book.bookName >> book.author >> book.publisher >> book.price >> book.category){
		if(bookName == book.bookName){
           // result = true;
            
            if(!result)
            // 打印表头
            	cout << "\n编号\t书名\t作者\t出版社\t价格\t分类" << endl;   
            
          	 
            /*这里的表头会多次输出,解决方法 
           			 1 放到循环外部  任何时候都会输出
                     2.将 result = true;	反倒后方		*/
        	cout << book.no << "\t";
			cout << book.bookName << "\t";
			cout << book.author << "\t";
			cout << book.publisher << "\t";
			cout << book.price << "\t";
			cout << book.category << endl;
             result = true;
            // break;//这里的书名可能会重复
        }
        
    }
     //判断是否存在
    if(!result){
        cout << "该图书不存在" << endl;
    }
}
  

void searchBook(){
	cout << " 请选择查询方式:" << endl;
    cout << "1. 按编号查询" << endl;
	cout << "2.按书名查询" << endl;
    
    int type;
    cin >> type;
    
    if(type == 1){
        searchByNo();
    }else if(type == 2){
       searchByName();
    }else{
        cout << "输入错误,请重新输入" << endl;
        searchBook();
    }
}


void modifyBook() {
    cout << "请输入要修改的图书编号:" << endl;
    int no;
    cin >> no;
    ifstream in("book.txt");
    vector<Book> bookList; 
    Book book1;
    bool result = false; // 判断是否找到图书

    // 将文件数据读取到 bookList 中
    while (in >> book1.no >> book1.bookName >> book1.author >> book1.publisher >> book1.price >> book1.category) {
        bookList.push_back(book1);
    }
    in.close();
    
    // 遍历图书列表,查找需要修改的图书
    for (int i = 0; i < bookList.size(); i++) {
        Book& book2 = bookList[i];  // 使用引用来直接修改 bookList 中的数据
        
        // 判断图书编号是否匹配
        if (book2.no == no) {
            // 输出当前图书信息
            cout << "编号\t书名\t作者\t出版社\t价格\t分类" << endl;  
            cout <<  book2.no << "\t";  
            cout <<  book2.bookName << "\t";  
            cout <<  book2.author << "\t";  
            cout <<  book2.publisher << "\t";  
            cout <<  book2.price << "\t";  
            cout <<  book2.category << endl;

            // 修改数据
            result = true;
            book2.no = inputNo();
            book2.bookName = inputbookName();
            book2.author = inputAuthor();
            book2.publisher = inputPublisher();
            book2.price = inputPrice();
            book2.category = inputCategory();
            break;  // 找到并修改后退出循环
        }
    }

    // 如果没有找到该编号,输出提示信息
    if (!result) {
        cout << "该编号不存在" << endl;
    } else {
        // 将修改后的数据写回到文件
        ofstream o("book.txt");  // 打开文件进行写入
        if (o.is_open()) {
            // 遍历修改后的 bookList 并写回文件
            for (int i = 0; i < bookList.size(); i++) {
                Book& book2 = bookList[i];
                o << book2.no << " " << book2.bookName << " " << book2.author << " "
                  << book2.publisher << " " << book2.price << " " << book2.category << endl;
            }
            o.close();  // 完成写入后关闭文件流
            cout << "修改成功" << endl;
        } else {
            cout << "文件写入失败!" << endl;
        }
    }
}





//根据用户输入的功能码选择功能函数 
void choose(int input){
	system("cls");
	switch(input){
		case 1: 
		cout << "你选择了添加功能" << endl ; 
			add();
			break;
		case 2: 
		cout << "你选择了删除功能" << endl ; 
			del(); 
			break;
		case 3: 
		cout << "你选择了修改功能" << endl ; 
			modifyBook();
			break;
		case 4: 
		cout << "你选择了列表功能" << endl ; 
			list(); 
			break;
		case 5: 
		cout << "你选择了查询功能" << endl ; 
			searchBook();
			break;
		case 0:     //退出系统也会实现先暂停退出   希望将这个选项排除 
			//1.加判断if  
			//2.修改 break 为 return 
			cout << "退出系统" << endl ;
			return ;
		default:
			cout << "功能码错误" << endl; 
	}//不管执行什么方法都会去执行暂停以及清空 
	
	system("pause"); 
	system("cls");
}



int main(int argc, char** argv) {
	int input = 1;
	 while(input !=0){
	 	
		cout << "1.添加图书"<< endl; 
		cout << "2.删除图书"<< endl; 
		cout << "3.修改图书"<< endl; 
		cout << "4.图书列表"<< endl; 
		cout << "5.图书查询"<< endl;
		cout << "0.退出系统"<< endl;
		cout << "输入选择功能(0-5)"<< endl;
		//用户把输入的值赋值给input  input作为循环条件 
		// 
		cin >> input; 	
		choose (input);
	 	 
	 	
	 }
	
	return 0;
}

五、总结

本项目实现了一个简单的图书管理系统,展示了如何通过文件流操作实现增、删、改、查等常见的数据库操作。通过本项目,初学者可以深入理解C++的文件流操作、结构体的使用以及基本的算法实现。虽然当前系统较为简单,但可以作为更复杂应用的基础,进一步扩展功能和性能,后续实现数据库的实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Yhame.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值