Search and replace string in txt file in c++

余生长醉 提交于 2019-12-21 02:52:11

问题


I want to find a string in a file and replace it with user input.
Here is my rough code.

#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`?
        }
    }
}

UPDATE
Here is the code that solved my problem

test.txt:

id_1
arfan
haider

id_2
saleem
haider

id_3
someone
otherone

C++ Code:

#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;  
        }
    }
}  

Suppose:
A user searches for id id_2. After that user enter First name and Last name Shafiq and Ahmed. After runing this code the test.txt File must modify the record like that:

…

id_2
Shafiq
Ahmad

…

Only the id_2 record changes, the remaining file will stay the same.


回答1:


This should work. I used string::find to find the desired substring within each line, and string::replace to replace it if something has been found.

Edit: I forgot about the case where the word occurs multiple times per line. Added a while to fix this.

#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';
    }
}



回答2:


I would do what @stefaanv said:

#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;
    }
  }
}

Edit: the above solution works if the information on each line is independent of the information on the other lines. In your update, the information on the name lines is dependent on the information on the id lines. So, to extend the above technique, you'll need to maintain state in the while loop that indicates when you've reached the end of one data block.

#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;
    }
  }
}

A slightly more elegant approach would be to store each data block in a struct, which allows you to use overloaded operators << & >>. This makes the code for file reading & writing more clear - it's practically the same as the code for the "data on each line is independent" situation.

#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;
    }
  }
} 



回答3:


#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;    
}

Usage:

./a.out old_word    new_word    filename


来源:https://stackoverflow.com/questions/21180412/search-and-replace-string-in-txt-file-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!