使用C++替换文件中指定单词时出现误替换问题求助
错误原因
- 读写指针位置错误:当你使用
file>>s1读到匹配的maaza字符串时,文件读指针已经移动到了maaza的末尾位置,此时直接执行file<<s1会把fanta写入到maaza后面的内容区域,覆盖了原本的换行、空格和后续的Cost :内容,就出现了你看到的Costfanta0的错误结果。 - 未按标准执行读写切换操作:C++标准规定,同一个
fstream对象在读操作和写操作切换时,必须先调用seekg/seekp调整指针位置,或者调用flush刷新缓冲区,否则属于未定义行为,你的代码直接在读完之后写,本身就不符合规范。 - 指针偏移计算缺失:即使要原地覆盖写入,你也需要将写指针回退到
maaza字符串的起始位置,也就是当前读指针位置减去目标字符串maaza的长度,才能正确覆盖原内容。
修复方案
方案1:原地修改(仅适用于替换前后字符串长度一致的场景,本次需求符合这个条件)
#include<iostream> #include<fstream> #include<string> using namespace std; int main(){ fstream file; string filename="stockk.txt"; // 明确指定读写模式打开 file.open(filename, ios::in | ios::out); if(!file.is_open()){ cout<<"文件打开失败"<<endl; return 1; } string s1; const string target = "maaza"; const string replace_str = "fanta"; int flag = 0; streampos pos; while(file >> s1){ if(s1 == target){ flag = 1; // 回退指针到target字符串的起始位置 pos = file.tellg(); file.seekp(pos - (streampos)target.size()); // 写入替换内容,因为长度一致直接覆盖即可 file << replace_str; break; } } if(flag == 0){ cout << "Go ahead"; } else { cout << "data already recorded at address " << pos; } file.close(); return 0; }
方案2:通用全量替换方案(适用于所有替换场景,不管替换前后长度是否一致)
逻辑是先把整个文件内容读到内存中完成替换,再清空原文件把替换后的内容写回去,避免指针操作错误:
#include<iostream> #include<fstream> #include<string> #include<sstream> using namespace std; int main(){ string filename = "stockk.txt"; // 第一步:读取整个文件内容 ifstream in_file(filename); if(!in_file.is_open()){ cout<<"文件打开失败"<<endl; return 1; } stringstream buffer; buffer << in_file.rdbuf(); string content = buffer.str(); in_file.close(); // 第二步:替换所有匹配的字符串 const string target = "maaza"; const string replace_str = "fanta"; size_t pos = 0; while((pos = content.find(target, pos)) != string::npos){ content.replace(pos, target.size(), replace_str); pos += replace_str.size(); } // 第三步:把替换后的内容写回文件 ofstream out_file(filename); out_file << content; out_file.close(); cout<<"替换完成"<<endl; return 0; }
内容的提问来源于stack exchange,提问作者Mahir Jain
相关产品推荐
相关产品推荐

