Home > Software engineering >  replacing string based on user input c
replacing string based on user input c

Time:12-20

i want to receive an input from user and search a file for that input. when i found a line that includes that specific word, i want to print it and get another input to change a part of that line based on second user input with third user input. (I'm writing a hospital management app and this is a part of project that patients and edit their document). i completed 90 percent of the project but i don't know how to replace it. check out following code:

#include <iostream>
#include <stream>
#include <string.h>
#include <string>
using namespace std; 

int main(){
    string srch;
    string line;
    fstream Myfile;
    string word, replacement, name;
    int counter;
    Myfile.open("Patientlist.txt", ios::in|ios::out);
    cout << "\nEnter your Name: ";
    cin.ignore();
    getline(cin, srch);

    if(Myfile.is_open())
    {
        while(getline(Myfile, line)){
            if (line.find(srch) != string::npos){
                cout << "\nYour details are: \n" << line << endl << "What do you want to change? *type it's word and then type the replacement!*" << endl;
                cin >> word >> replacement;
            } 
            // i want to change in here
        }
    }else
    {
        cout << "\nSearch Failed...  Patient not found!" << endl;
    }  
    Myfile.close();
    
    }

for example my file contains this line ( David , ha , 2002 ) and user wants to change 2002 to 2003

CodePudding user response:

Try this

#include <iostream>
#include <fstream>
#include <string.h>
#include <string>
using namespace std; 

int main(){
    string srch;
    string line, line2;
    fstream Myfile;
    string word, replacement, name;
    int counter;
    Myfile.open("Patientlist.txt", ios::in);
    cout << "\nEnter your Name: ";
    cin.ignore();
    getline(cin, srch);

    if(Myfile.is_open())
    {
        while(getline(Myfile, line)){
            if (line.find(srch) != string::npos){
                cout << "\nYour details are: \n" << line << endl << "What do you want to change? *type it's word and then type the replacement!*" << endl;
                cin >> word >> replacement;

                int index = line.find(word);

                if (index != string::npos){
                    Myfile.close();

                    Myfile.open("Patientlist.txt", ios::out);

                    line.replace(index, word.length(), replacement);
                    Myfile.write(line.data(), line.size());

                    Myfile.close();
                }
            } 
            // i want to change in here
        }
    }else
    {
        cout << "\nSearch Failed...  Patient not found!" << endl;
    }  
    
    
    }

First of all the header is supposed to be <fstream> rather than <stream>

I don't have much experience in File handling either but I have read that you can't read and write simultaneoudly so I have closed before reopening the file for writing.

Then, instead of updating text inside the file, your line can be updated and then written to file.

CodePudding user response:

One possible way: Close the file after you read it into "line" variable, then:

std::replace(0, line.length(), "2002", "2003")

Then overwrite the old file. Note that std::replace is different from string::replace!!

CodePudding user response:

You cannot replace the string directly in the file. You have to:

  1. Write to a temporary file what you read & changed.
  2. Rename the original one (or delete it if you are sure everything went fine).
  3. Rename the temporary file to the original one.

Ideally, the rename part should be done in one step. For instance, you do not want to end up with no file because the original file was deleted but the temporary one was not renamed due to some error - see your OS documentation for this.

Here's an idea:

#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>

using namespace std;

void replace(string& s, const string& old_str, const string& new_str)
{
  for (size_t off = 0, found_idx = s.find(old_str, off); found_idx != string::npos; found_idx = s.find(old_str, off), off  = new_str.length())
    s.replace(found_idx, old_str.length(), new_str);
}

int main()
{
  const char* in_fn = "c:/temp/in.txt";
  const char* bak_fn = "c:/temp/in.bak";
  const char* tmp_fn = "c:/temp/tmp.txt";
  const char* out_fn = "c:/temp/out.txt";

  string old_str{ "2002" };
  string new_str{ "2003" };

  // read, rename, write
  {
    ifstream in{ in_fn };
    if (!in)
      return -1; // could not open

    ofstream tmp{ tmp_fn };
    if (!tmp)
      return -2; // could not open

    string line;
    while (getline(in, line))
    {
      replace(line, old_str, new_str);
      tmp << line << endl;
    }
  } // in & tmp are closed here

  // this should be done in one step 
  {
    remove(bak_fn);
    rename(in_fn, bak_fn);

    remove(out_fn);
    rename(tmp_fn, in_fn);
  }

  return 0;
}
  • Related