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.
Open the text file in Notepad. Click Edit on the menu bar, then select Replace in the Edit menu. Once in the Search and Replace window, enter the text you want to find and the text you want to use as a replacement. See our using search and replace and advanced options section for further information and help.
The fastest way would be to allocate a new string that is strlen (s) - strlen (word) + strlen (rpwrd) + 1 . Then use the strstr function to find the word to be replaced and copy up to that point into a new string, append the new word, then copy the rest of the original sentence into a new string.
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';
}
}
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;
}
}
}
#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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With