C++书店管理系统程序

我做了一个书店管理系统的C++程序,目前存在以下错误:
1、在VS code中调试程序,中文部分全部为乱码,更改cpp文件编码格式(UTF-8和ANSI)都没有用
2、保存图书信息时会覆盖掉过去的记录
3、图书信息查询时,不能正常查询
(包括:不能从读取的数据中获取信息,例如:我在data.txt中录入了图书A的信息,程序成功读取该文件,但不能查找到这本书;当此录入书籍后不能正常查询)
请帮我检查一下是哪里出了问题?

#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <set>
#include <ctime>
#include <iomanip>
#include <windows.h>

using namespace std;

class Book {
public:
    string name;
    string author;
    string publisher;
    int pages;
    time_t latest_time;
    int stock;
    double price;

    Book(string n, string a, string p, int pg, int s, double pr) {
        name = n;
        author = a;
        publisher = p;
        pages = pg;
        latest_time = time(NULL);
        stock = s;
        price = pr;
    }

    friend ostream& operator<<(ostream& os, const Book& book) {
        os << "图书书名:" << book.name << endl;
        os << "图书作者:" << book.author << endl;
        os << "图书出版社:" << book.publisher << endl;
        os << "图书页数:" << book.pages << endl;
        os << "最新入库时间:" << put_time(localtime(&book.latest_time), "%Y-%m-%d %H:%M:%S") << endl;
        os << "图书库存量:" << book.stock << endl;
        os << "图书价格:" << book.price << endl;
        return os;
    }
};

class PurchaseRecord {
public:
    string name;
    string author;
    string publisher;
    int pages;
    time_t time1;
    int quantity;
    double price;

    PurchaseRecord(string n, string a, string p, int pg, int q, double pr) {
        name = n;
        author = a;
        publisher = p;
        pages = pg;
        time1 = time(NULL);
        quantity = q;
        price = pr;
    }

    friend ostream& operator<<(ostream& os, const PurchaseRecord& record) {
        os << "图书书名:" << record.name << endl;
        os << "图书作者:" << record.author << endl;
        os << "图书出版社:" << record.publisher << endl;
        os << "图书页数:" << record.pages << endl;
        os << "图书入库时间:" << put_time(localtime(&record.time1), "%Y-%m-%d %H:%M:%S") << endl;
        os << "图书进货数量:" << record.quantity << endl;
        os << "图书进货价格:" << record.price << endl;
        return os;
    }
};

class SalesRecord {
public:
    string name;
    string author;
    string publisher;
    int pages;
    time_t time2;
    int quantity;
    double price;

    SalesRecord (string n, string a, string p, int pg, int q, double pr) {
        name = n;
        author = a;
        publisher = p;
        pages = pg;
        time2 = time(NULL);
        quantity = q;
        price = pr;
    }

friend ostream& operator<<(ostream& os, const SalesRecord& record) {
    os << "图书书名:" << record.name << endl;
    os << "图书作者:" << record.author << endl;
    os << "图书出版社:" << record.publisher << endl;
    os << "图书页数:" << record.pages << endl;
    os << "图书销售时间:" << put_time(localtime(&record.time2), "%Y-%m-%d %H:%M:%S") << endl;
    os << "图书销售数量:" << record.quantity << endl;
    os << "图书销售价格:" << record.price << endl;
    return os;
}
};

class Bookstore
{
private:
vector<Book> books;
vector<PurchaseRecord> purchase_records;
vector<SalesRecord> sales_records;
set<string> warning_books;

public:
void add_book(string n, string a, string p, int pg, int s, double pr)
{
    Book book(n, a, p, pg, s, pr); books.push_back(book);
     }

void purchase(string n, string a, string p, int pg, int q, double pr) {
    PurchaseRecord record(n, a, p, pg, q, pr);
    purchase_records.push_back(record);

    for (auto& book : books) {
        if (book.name == n && book.author == a && book.publisher == p && book.pages == pg) {
            book.stock += q;
            book.latest_time = time(NULL);
            if (book.stock <= 1) {
                warning_books.insert(n);
            }
            return;
        }
    }

    add_book(n, a, p, pg, q, pr);
    warning_books.insert(n);
}

void sell(string n, string a, string p, int pg, int q, double pr) {
    SalesRecord record(n, a, p, pg, q, pr);
    sales_records.push_back(record);

    for (auto& book : books) {
        if (book.name == n && book.author == a && book.publisher == p && book.pages == pg) {
            book.stock -= q;
            book.latest_time = time(NULL);
            if (book.stock <= 1) {
                warning_books.insert(n);
            }
            return;
        }
    }
}
void query_book(string n, string a)
{
for (auto& book : books) {
if (book.name == n && book.author == a)
 {
cout << book << endl;
 return;
}
}

cout << "Error Message : Warning! The book information was not found! Please enter the correct book information!" << endl;
 }

void warning()
{
    if (warning_books.empty())
    {
        
        cout << "Message : There are currently no books that require warning!" << endl;
        return;
        }
        
        cout << "Message : The inventory of the following books is 1. Please purchase them in a timely manner:" << endl;
        for (auto& book : warning_books)
        {
            cout << book << endl;
            }
        }

void save_data()
{
    ofstream fout("data.txt");
    if (!fout)
    {
        
        cout << "Error Message : File opening failed!"<< endl;
        return;
        }

fout << "图书信息:" << endl;
for (auto& book : books) {
    fout << book << endl;
}

fout << "图书进货记录:" << endl;
for (auto& record : purchase_records) {
    fout << record << endl;
}

fout << "图书销售记录:" << endl;
for (auto& record : sales_records) {
    fout << record << endl;
}

fout.close();

cout << "Message : Data saved successfully!" << endl;
}

void load_data()
{
ifstream fin("data.txt");
if (!fin) {
    
    cout << "Error Message : File opening failed!" << endl;
return;
}

string line;
while (getline(fin, line)) {
    if (line == "图书信息:") {
        while (getline(fin, line) && line != "进货记录:") {
            string name, author, publisher;
            int pages, stock;
            double price;
            time_t latest_time;
            sscanf(line.c_str(), "书名:%s 作者:%s 出版社:%s 页数:%d 最新入库时间:%ld 库存量:%d 价格:%lf",
                &name, &author, &publisher, &pages, &latest_time, &stock, &price);
            Book book(name, author, publisher, pages, stock, price);
            book.latest_time = latest_time;
            books.push_back(book);
            if (stock == 1) {
                warning_books.insert(name);
            }
        }
    }
    else if (line == "进货记录:") {
        while (getline(fin, line) && line != "销售记录:") {
            string name, author, publisher;
            int pages, quantity;
            double price;
            time_t time;
            sscanf(line.c_str(), "书名:%s 作者:%s 出版社:%s 页数:%d 入库时间:%ld 进货数量:%d 进货价格:%lf",
                &name, &author, &publisher, &pages, &time, &quantity, &price);
            PurchaseRecord record(name, author, publisher, pages, quantity, price);
            record.time1 = time;
            purchase_records.push_back(record);
        }
    }
    else if (line == "销售记录:") {
        while (getline(fin, line)) {
            string name, author, publisher;
            int pages, quantity;
            double price;
            time_t time;
            sscanf(line.c_str(), "书名:%s 作者:%s 出版社:%s 页数:%d 销售时间:%ld 销售数量:%d 销售价格:%lf",
            &name, &author, &publisher, &pages, &time, &quantity, &price);
            SalesRecord record(name, author, publisher, pages, quantity, price);
            record.time2 = time;
            sales_records.push_back(record);
            }
            }
            }

fin.close();

cout << "Message : Data read successful!"<< endl;
}

void show_menu() {
    cout << "欢迎使用书店管理系统!" << endl;
    cout << "1. 添加图书" << endl;
    cout << "2. 进货入库" << endl;
    cout << "3. 销售出货" << endl;
    cout << "4. 查询图书信息" << endl;
    cout << "5. 自动预警提示" << endl;
    cout << "6. 保存数据到文件" << endl;
    cout << "7. 从文件中读取数据" << endl;
    cout << "0. 退出系统" << endl;
    cout << "请输入操作编号:";
    }

void run() {
    int choice;
    while (true) {
        show_menu();
        cin >> choice;
        switch (choice) {
            case 1: {
                string name, author, publisher;
                int pages, stock; double price;
                cout << "请输入书名:"; cin >> name;
                cout << "请输入作者:"; cin >> author;
                cout << "请输入出版社:"; cin >> publisher;
                cout << "请输入页数:"; cin >> pages;
                cout << "请输入库存量:"; cin >> stock;
                cout << "请输入价格:"; cin >> price;
                add_book(name, author, publisher, pages, stock, price);
                
                cout << "Message : Book added successfully!"<< endl;
                break;
                }
                case 2: {
                    string name, author, publisher;
                    int pages, quantity;
                    double price;
                    cout << "请输入书名:";
                    cin >> name;
                    cout << "请输入作者:";
                    cin >> author;
                    cout << "请输入出版社:";
                    cin >> publisher;
                    cout << "请输入页数:";
                    cin >> pages;
                    cout << "请输入进货数量:";
                    cin >> quantity;
                    cout << "请输入进货价格:";
                    cin >> price;
                    purchase(name, author, publisher, pages, quantity, price);
                    cout << "Message : Succeeded in purchasing and warehousing!" << endl;
                    break;
                    }
                    case 3: {
                        string name, author, publisher;
                        int pages, quantity;
                        double price;
                        cout << "请输入书名:";
                        cin >> name;
                        cout << "请输入作者:";
                        cin >> author;
                        cout << "请输入出版社:";
                        cin >> publisher;
                        cout << "请输入页数:";
                        cin >> pages;
                        cout << "请输入销售数量:";
                        cin >> quantity;
                        cout << "请输入销售价格:";
                        cin >> price;
                        sell(name, author, publisher, pages, quantity, price);
                        
                        cout << "Message : Sales shipment successful!" << endl;
                        break;
                        }
                    case 4: {
                        string name, author;
                        cout << "请输入书名:";
                        cin >> name;
                        cout << "请输入作者:";
                        cin >> author;
                        query_book(name, author);
                        break;
                        }
                    case 5: {
                        warning();
                        break;
                        }
                    case 6: {
                        save_data();
                        break;
                        }
                    case 7: {
                        load_data();
                        break;
                        }
                    case 0: {
                        cout << "感谢使用书店管理系统,再见!" << endl;
                        return;
                        }
                    default: {
                        
                        cout << "Error Message : Warning! No valid input information detected! Please re-enter!" << endl;
                        break;
                        }
                    }
                }
            }
};
int main()
{
    Bookstore bookstore;
    bookstore.run();
    return 0;
}


不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    可能出现了几个问题,需要逐一排查:

    1. 中文乱码:

    首先需要确保源代码文件的编码格式为UTF-8,并且在保存时选择“以UTF-8_WITH_BOM格式保存”(VS code中的设置可以通过Ctrl+Shift+P打开命令面板,搜索“文件编码”)。如果还是出现乱码,则需要在程序中添加代码以支持中文输出:

    #include <iostream>
    #include <locale>
    using namespace std;
    
    int main() {
        // 设置标准输出流的本地化类型为中文
        wcout.imbue(locale("chs"));
        // 输出中文
        wcout << L"你好,世界!" << endl;
        return 0;
    }
    

    上述代码中,wcout是一个输出流对象,通过调用它的imbue()方法来设置输出流的本地化类型为中文,然后就可以通过wcout输出支持中文的字符串了。

    1. 保存记录时覆盖以前记录:

    这个问题可能是由于每次保存时都是以覆盖写文件的方式实现的,而没有将新记录追加到文件的末尾。可以通过以下代码实现:

    #include <fstream>
    using namespace std;
    
    int main() {
        // 打开文件
        ofstream fout("data.txt", ios::app);
        // 写入数据
        fout << "book_A" << ',' << "author_A" << ',' << 100 << endl;
        // 关闭文件
        fout.close();
        return 0;
    }
    

    上述代码中,ofstream是一个输出文件流对象,通过设置打开方式为ios::app就可以实现追加写入文件。每次保存新记录时,就将新记录追加到文件末尾即可。

    1. 查询记录时出现问题:

    这个问题可能是由于查询条件不正确或数据格式不规范导致的。可以添加一些调试代码来查看程序的执行过程和变量值,以便快速定位问题。例如:

    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
    
    int main() {
        // 读取文件
        ifstream fin("data.txt");
        string line;
        while (getline(fin, line)) {
            // 调试代码
            cout << line << endl;
            // 解析数据
            // ...
        }
        // 关闭文件
        fin.close();
        return 0;
    }
    

    上述代码中,ifstream是一个输入文件流对象,通过getline()方法每次读取一行文件,并将该行文件输出到控制台以便调试。然后就可以查看输出结果,看看数据格式是否正确。如果数据格式不规范,可以添加一些代码来对数据进行格式化处理,以方便查询。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

综合GPT的回答:

文件内容你可能不是以追加的方式打开的文件

#include <iostream>
#include <fstream>

int main() {
    std::ofstream file("filename.txt", std::ios::app); // 打开文件以追加方式写入

    if (file) {
        file << "追加的内容" << std::endl;
        file.close();
        std::cout << "内容已追加到文件中" << std::endl;
    } else {
        std::cout << "无法打开文件" << std::endl;
    }

    return 0;
}

在C++中读取文件时遇到中文乱码问题,通常是由于编码方式不匹配导致的。下面是一些解决该问题的方法:
  1. 确定文件的编码方式:首先要确定文件的编码方式是什么,常见的编码方式有UTF-8、GBK等。可以使用文本编辑器打开文件并查看编码方式,或者使用其他工具进行检测。

  2. 使用正确的编码方式打开文件:在C++中,使用标准库的方式打开文件可能会使用默认的编码方式,这可能导致中文乱码。为了避免这个问题,可以使用适当的编码方式打开文件。例如,使用std::wifstream代替std::ifstream,并使用std::locale设置合适的编码方式,如下所示:

#include <iostream>
#include <fstream>
#include <locale>

int main() {
    std::wifstream file("filename.txt");
    file.imbue(std::locale("")); // 使用系统默认的编码方式

    if (file) {
        std::wstring line;
        while (getline(file, line)) {
            std::wcout << line << std::endl;
        }
    } else {
        std::cout << "无法打开文件" << std::endl;
    }

    return 0;
}
  1. 转换编码方式:如果文件的编码方式与C++所使用的编码方式不兼容,可以使用第三方库进行编码转换。例如,可以使用iconv库来进行编码转换。这个库提供了一种简单的方式将一个编码转换为另一个编码。你可以在代码中使用iconv库函数将文件内容从一种编码方式转换为另一种编码方式,然后再进行处理。
#include <iostream>
#include <fstream>
#include <iconv.h>

int main() {
    std::ifstream file("filename.txt");
    if (file) {
        std::string line;
        while (getline(file, line)) {
            // 将line从GBK编码转换为UTF-8编码
            std::string convertedLine = convertEncoding(line, "GBK", "UTF-8");
            std::cout << convertedLine << std::endl;
        }
    } else {
        std::cout << "无法打开文件" << std::endl;
    }

    return 0;
}

std::string convertEncoding(const std::string& str, const char* fromEncoding, const char* toEncoding) {
    iconv_t converter = iconv_open(toEncoding, fromEncoding);
    if (converter == (iconv_t)-1) {
        std::cerr << "无法打开编码转换器" << std::endl;
        return "";
    }

    size_t inBytes = str.length();
    size_t outBytes = inBytes * 2;  // 估计输出缓冲区大小为输入的两倍
    char* inBuffer = const_cast<char*>(str.c_str());
    char* outBuffer = new char[outBytes];
    char* outBufferPtr = outBuffer;

    if (iconv(converter, &inBuffer, &inBytes, &outBufferPtr, &out

Bytes) == (size_t)-1) {
        std::cerr << "编码转换失败" << std::endl;
        delete[] outBuffer;
        iconv_close(converter);
        return "";
    }

    std::string convertedString(outBuffer, outBufferPtr - outBuffer);
    delete[] outBuffer;
    iconv_close(converter);

    return convertedString;
}

这些方法应该能够帮助你解决C++读取文件时的中文乱码问题。根据你的具体情况选择合适的方法进行处理。