So I have a file of strings that I am reading in, and I have to replace certain values in them with other values. The amount of possible replacements is variable. As in, it reads the patterns to replace with in from a file. Currently I'm storing in a vector<pair<string,string>> for the patterns to find and match. However I run into issues:
Example:
Input string:
abcd.eaef%afas&333Delimiter patterns:
. %%%
% ###
& @@@Output I want:
abcd%%%eaef###afas@@@333Output I get:
abcd#########eaef###afas@@@333
The issue being it ends up replacing the % sign or any other symbol that was already a replacement for something else, it should not be doing that.
My code is (relevant portions):
std::string& replace(std::string& s, const std::string& from, const std::string& to){
if(!from.empty())
for(size_t pos = 0; (pos = s.find(from, pos)) != std::string::npos; pos += to.size()) s.replace(pos, from.size(), to);
return s;
}
string line;
vector<pair<string, string>> myset;
while(getline(delimiterfile, line)){
istringstream is(line);
string delim, pattern;
if(is >> delim >> pattern){
myset.push_back(make_pair(delim, pattern));
} else {
throw runtime_error("Invalid pattern pair!");
}
}
while(getline(input, line)){
string temp = line;
for(auto &item : myset){
replace(temp, item.first, item.second);
}
output << temp << endl;
}
Can someone please tell me what I'm messing up and how to fix it?
>>operator for something like this is absolutely the wrong way to do it, and introduces completely unnecessary complications related to formatted input operators. The correct way to do this is to loop over the string, check if each character is the one that needs to be replaced, if not copy it to the destination string, else copy the replacement. That's it. End of story. A simple for loop is going to be much easier than this overengineered tangled mass of spaghetti."."with"%%%"which you then replace with three sets of"###". When you made a replacement, don't start over from the beginning, start with the next character after the recent replacement.