C++实现txt文件键值行更新或不存在则新增功能异常排查
键值文本存储功能实现修复
需求描述
实现基于txt文件的简易键值读写逻辑:
- 若文件中存在以指定key开头的键值行,将该行替换为
key=value格式 - 若文件中不存在对应key的行,在文件末尾新增该键值行
现存问题
之前编写的多版代码存在两类典型错误:
- 直接覆盖原文件,导致原有非目标键值行被全部删除
- 写入逻辑错误,运行后完全不向文件写入有效内容
重要提示:问题版本代码运行后无任何有效写入效果
原代码Bug定位
逐行排查后问题点如下:
- 新增键值的逻辑位置错误:将
!found判断放在逐行读取的循环内部,会导致每读一行未匹配到key就重复写入一次键值对,生成大量冗余内容 - 文件替换流程缺失:仅执行了
remove("test.txt")删除原文件,没有将临时生成的tempTest.txt重命名为test.txt,修改后的内容仅存在于临时文件中,原文件被删除后新文件未生效,最终看不到写入结果 - 匹配逻辑存在误判风险:仅通过
line.find(key) == 0判断行首包含key字符串,未校验key后是否为键值分隔符=,例如key为port时,行首为portable=1的行也会被误匹配替换 - 流关闭时机和文件操作的顺序没有做兼容处理,容易出现文件占用导致的操作失败
修复后完整代码
#include <fstream> #include <string> #include <cstdio> #include <iostream> using namespace std; void edit(const char* key, const char* value) { ifstream filein("test.txt"); ofstream fileout("tempTest.txt"); if (!filein.is_open() || !fileout.is_open()) { cout << "Error opening files!" << endl; return; } bool found = false; string line; const string match_prefix = string(key) + "="; while (getline(filein, line)) { // 匹配行首为key=的行,避免误匹配 if (line.rfind(match_prefix, 0) == 0) { fileout << key << "=" << value << '\n'; found = true; } else { fileout << line << '\n'; } } // 全量读取完原文件后,未找到匹配key才追加新行 if (!found) { fileout << key << "=" << value << '\n'; } // 先关闭文件流,释放文件占用再执行文件系统操作 filein.close(); fileout.close(); // 完成临时文件替换原文件的流程 remove("test.txt"); rename("tempTest.txt", "test.txt"); }
实现逻辑说明
- 采用临时文件中转的写入方式,避免直接打开原文件写入截断导致的原有内容丢失
- 匹配键值行时使用
key=作为匹配前缀,彻底解决短key误匹配长字段的问题 - 新增键值的逻辑放在原文件全量读取完成之后,仅当确认没有匹配行时才执行追加
- 文件流关闭后再执行删除、重命名的文件系统操作,规避跨平台文件占用的问题
内容的提问来源于stack exchange,提问作者Pixel Coin
相关产品推荐
相关产品推荐

