You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据参考号条件更新TXT文件中的商品信息?

控制台库存管理程序更新功能异常问题

我正在开发一个学校项目的基础控制台库存管理程序(非SQL相关),通过struct创建商品并写入database.txt文件。现在需要根据商品的参考号(格式为REF:)找到对应条目,更新该参考号下直至下一个参考号的所有内容,但运行代码后出现异常。

当前代码

if(button2 == 2)
{
    string refNo;
    string word;
    cout <<"Enter the referance number of item for update" << endl;
    cin >> refNo;
    refNo = "REF:"+refNo;
    fstream file(databaseFile.c_str());
    if(file.is_open())
    {
        while(getline(file, word))
        {
            if(word == refNo)
            {
                product entity = createItem(true);
                file << entity.detail.category << endl;
                file << entity.name << endl;
                file << entity.price << endl;
                file << entity.profitMargine << endl;
                file << entity.stock << endl;
            }
        }
    }
}

问题原因

  1. 文件读写模式错误:默认fstream打开方式为in|out,写入时仅覆盖当前指针位置的内容,不会替换整段条目,导致新旧内容混杂。
  2. 未处理原有条目数据:找到目标REF后直接写入新内容,但原有条目下的旧数据未被移除,残留于文件中。
  3. 指针位置逻辑错误:getline移动文件指针后,写入操作是在当前位置追加/覆盖,而非从REF开始替换后续行。

解决方法

正确流程是先将文件内容全部读入内存,修改后重新写入文件,步骤如下:

修改后的代码示例

#include <iostream>
#include <fstream>
#include <vector>
#include <string>

// 假设已有product结构体定义
struct product {
    struct {
        std::string category;
    } detail;
    std::string name;
    double price;
    double profitMargine;
    int stock;
};

// 假设createItem函数用于获取更新后的商品信息
product createItem(bool isUpdate) {
    product p;
    std::cout << "输入商品分类: ";
    std::cin >> p.detail.category;
    std::cout << "输入商品名称: ";
    std::cin >> p.name;
    std::cout << "输入商品价格: ";
    std::cin >> p.price;
    std::cout << "输入利润率: ";
    std::cin >> p.profitMargine;
    std::cout << "输入库存数量: ";
    std::cin >> p.stock;
    return p;
}

int main() {
    int button2 = 2;
    const std::string databaseFile = "database.txt";

    if (button2 == 2) {
        std::string refNo;
        std::cout << "输入要更新的商品参考号: ";
        std::cin >> refNo;
        refNo = "REF:" + refNo;

        // 1. 读取文件全部内容到内存
        std::vector<std::string> fileLines;
        std::string line;
        std::ifstream inFile(databaseFile);
        if (inFile.is_open()) {
            while (std::getline(inFile, line)) {
                fileLines.push_back(line);
            }
            inFile.close();
        } else {
            std::cout << "无法打开文件读取内容" << std::endl;
            return 1;
        }

        // 2. 定位目标REF及需要替换的行范围
        bool refFound = false;
        int startIdx = -1;
        int endIdx = fileLines.size() - 1;

        for (int i = 0; i < fileLines.size(); ++i) {
            if (fileLines[i] == refNo) {
                refFound = true;
                startIdx = i;
                // 查找下一个REF的位置,确定替换结束点
                for (int j = i + 1; j < fileLines.size(); ++j) {
                    if (fileLines[j].substr(0, 4) == "REF:") {
                        endIdx = j - 1;
                        break;
                    }
                }
                break;
            }
        }

        // 3. 替换条目内容并重新写入文件
        if (refFound) {
            product updatedItem = createItem(true);
            // 删除原有条目下的旧内容
            fileLines.erase(fileLines.begin() + startIdx + 1, fileLines.begin() + endIdx + 1);
            // 插入新的商品信息(注意顺序要和写入时一致)
            fileLines.insert(fileLines.begin() + startIdx + 1, std::to_string(updatedItem.stock));
            fileLines.insert(fileLines.begin() + startIdx + 1, std::to_string(updatedItem.profitMargine));
            fileLines.insert(fileLines.begin() + startIdx + 1, std::to_string(updatedItem.price));
            fileLines.insert(fileLines.begin() + startIdx + 1, updatedItem.name);
            fileLines.insert(fileLines.begin() + startIdx + 1, updatedItem.detail.category);

            // 写入修改后的内容
            std::ofstream outFile(databaseFile);
            if (outFile.is_open()) {
                for (const auto& l : fileLines) {
                    outFile << l << std::endl;
                }
                outFile.close();
                std::cout << "商品信息更新成功" << std::endl;
            } else {
                std::cout << "无法打开文件写入内容" << std::endl;
            }
        } else {
            std::cout << "未找到参考号为 " << refNo << " 的商品" << std::endl;
        }
    }

    return 0;
}

关键步骤说明

  • 内存中修改:将文件内容读入vector<string>,避免直接操作文件导致的指针混乱和内容残留问题。
  • 精准定位范围:找到目标REF后,定位到下一个REF的位置,确保只替换当前条目下的内容。
  • 全量重写:修改完成后将整个内存中的内容重新写入文件,保证文件结构的完整性。

内容的提问来源于stack exchange,提问作者Alperen Usta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 02:45:23