在 c++ 中搜索和替换 txt 文件中的字符串

Search and replace string in txt file in c++

本文关键字:文件 txt 字符串 c++ 搜索 替换      更新时间:2023-10-16

我想在文件中查找一个字符串并将其替换为用户输入。
这是我的粗略代码。

#include <iostream>
#include <fstream.h>
#include <string.h>
int main(){
    istream readFile("test.txt");
    string readout,
         search,
         replace;
    while(getline(readFile,readout)){
        if(readout == search){
            // How do I replace `readout` with `replace`?
        }
    }
}

更新
这是解决我问题的代码

测试.txt:

id_1
arfan
haider
id_2
saleem
haider
id_3
someone
otherone

C++代码:

#include <iostream>
#include <fstream>
#include <string>
using namesapce std;
int main(){
    istream readFile("test.txt");
    string readout,
           search,
           firstname,
           lastname;
    cout << "Enter the id which you want to modify";
    cin >> search;
    while(getline(readFile,readout)){
        if(readout == search){
            /*
                id remains the same
                But the First name and Last name are replaced with
                the user `firstname` and `lastname` input
            */
            cout << "Enter new First name";
            cin >> firstname;
            cout << "Enter Last name";
            cin >> lastname;  
        }
    }
}  

假设:
用户搜索 ID id_2 。在该用户之后,输入名字和姓氏ShafiqAhmed。运行此代码后,test.txt文件必须像这样修改记录:

…
id_2
Shafiq
Ahmad
…

只有id_2记录会更改,其余文件将保持不变。

这应该有效。我使用 string::find 在每行中找到所需的子字符串,如果找到某些内容,string::replace替换它。

编辑:我忘记了单词每行多次出现的情况。添加了一个while来解决此问题。

#include <fstream>
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
    ifstream in(argv[1]);
    ofstream out(argv[2]);
    string wordToReplace(argv[3]);
    string wordToReplaceWith(argv[4]);
    if (!in)
    {
        cerr << "Could not open " << argv[1] << "n";
        return 1;
    }
    if (!out)
    {
        cerr << "Could not open " << argv[2] << "n";
        return 1;
    }
    string line;
    size_t len = wordToReplace.length();
    while (getline(in, line))
    {
        while (true)
        {
            size_t pos = line.find(wordToReplace);
            if (pos != string::npos)
                line.replace(pos, len, wordToReplaceWith);
            else 
                break;
        }
        out << line << 'n';
    }
}

我会按照@stefaanv所说的去做:

#include <iostream>
#include <fstream.h>
#include <string.h>
int main(){
  ostream outFile("replaced.txt");
  istream readFile("test.txt");
  string readout;
  string search;
  string replace;
  while(getline(readFile,readout)){
    if(readout == search){
      outFile << replace;
    }
    else {
      outFile << readout;
    }
  }
}

编辑:如果每行上的信息独立于其他行上的信息,则上述解决方案有效。 在更新中,名称行上的信息取决于 id 行上的信息。 因此,要扩展上述技术,您需要在 while 循环中维护状态,该状态指示何时到达一个数据块的末尾。

#include <iostream>
#include <fstream.h>
#include <string.h>
int main(){
  ostream outFile("replaced.txt");
  istream readFile("test.txt");
  string readout;
  string search, Fname, Lname;
  unsigned int skipLines = 0;
  cout << "Enter id which you want Modify";
  cin >> search;
  cout << "Enter new First name";
  cin >> Fname;
  cout << "Enter Last name";
  cin >> Lname;  
  while(getline(readFile,readout)) {
    if (skipLines != 0) {
      skipLines--;
      continue;
    }
    else if (readout == search) {
      outFile << search << endl;
      outFile << Fname << endl;
      outFile << Lname << endl;
      skipLines = 2;
    }
    else {
      outFile << readout;
    }
  }
}

一种稍微优雅的方法是将每个数据块存储在结构中,这允许您使用重载运算符<<和>>。 这使得文件读写的代码更加清晰 - 它实际上与"每行数据独立"情况下的代码相同。

#include <iostream>
#include <fstream.h>
#include <string.h>
struct NameRecord {
  string id;
  string fname;
  string lname;
  friend std::ostream& operator<<(std::ostream &os, const NameRecord &src);
  friend std::istream& operator>>(std::istream &is, NameRecord &dst);
};
std::ostream& operator <<(std::ostream &os, const NameRecord &src) {
  os << src.id << endl << src.fname << endl << src.lname << endl;
  return os;
}
std::istream& operator >>(std::istream &is, NameRecord &dst) {
  // may need to have more code to ignore whitespace, I'm not sure
  if (is.good ()) {
    is >> dst.id;
  }
  if (is.good ()) {
    is >> dst.fname;
  }
  if (is.good ()) {
    is >> dst.lname;
  }
  return is;
}
int main(){
  ostream outFile("replaced.txt");
  istream readFile("test.txt");
  NameRecord inRecord, replaceRecord;
  cout << "Enter id which you want Modify";
  cin >> replaceRecord.id;
  cout << "Enter new First name";
  cin >> replaceRecord.Fname;
  cout << "Enter Last name";
  cin >> replaceRecord.Lname;  
  while (readFile.good()) {
    // the >> operator reads the whole record (id, fname, lname)
    readFile >> inRecord;
    // the << operator writes the whole record
    if (inRecord.id == replaceRecord.id) {
      outFile << replaceRecord;
    }
    else {
      outFile << inRecord;
    }
  }
} 
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char **argv) {
if (argc < 4) {
    cout << "Invalid input" << endl;
    cout << "tchange <old_word> <new_word> <file_list>";
}
fstream fs;
string tmp;
string oldw = argv[1];
string neww = argv[2];
for (int i = 3; i < argc; i++) {
    fs.open(argv[i] , ios::in);
    while (!fs.eof()) {
        getline(fs, tmp);
        while (tmp.find(oldw) != string::npos)
            tmp.replace(tmp.find(oldw), sizeof(oldw), neww);    
        cout << tmp << endl;
    }
}
fs.close();
return 0;    
}

用法:

./a.out old_word    new_word    filename

你可能想写:

tmp.replace(tmp.find(oldw), oldw.length(), neww);   

以便正常工作。 sizeof()很可能总是返回 4。