Reputation: 2093
I've got a string which contains a sentence. I have to search and replace a specific word in that string. In my case I have a vector of lines and another vector of words to replace. Here's my function that generates a file with the final text:
void Generator::generate_file(const string& fileName){
string inBuffer, outBuffer;
std::stringstream ss;
std::ofstream outFile;
outFile.open(fileName);
for (const auto& inIT : userCode){
//userCode is a vector which contains lines of text
ss.str(inIT);
ss.clear();
outBuffer = "";
while (ss >> inBuffer){
for (auto keyIT : keywords){
//keywords is a vector which contains words to replace
if (keyIT == inBuffer)
inBuffer = "REPLACED";
}
outBuffer += inBuffer + " ";
}
outFile << outBuffer << endl;
}
outFile.close();
}
The problem with this function is that it skips all whitespaces. I need them in the output file. What should I do to achieve that? Below you can see an example of how it works:
userCode:
userCode[0] = "class UrlEncoder(object): class";
userCode[1] = " def __init__(self, alphabet=DEFAULT_ALPHABET,\n block_size=DEFAULT_BLOCK_SIZE):";
Displaying the userCode vector:
class UrlEncoder(object):
def __init__(self, alphabet=DEFAULT_ALPHABET, block_size=DEFAULT_BLOCK_SIZE):
After executing my function it looks like this:
REPLACED UrlEncoder(object):
REPLACED __init__(self, alphabet=DEFAULT_ALPHABET, block_size=DEFAULT_BLOCK_SIZE):
As you can see it properly replaced the keywords. But unfortunately it skipped the tabulator.
Upvotes: 1
Views: 84
Reputation: 20858
The main issue is the way the stream extraction >>
operator works. It removes and discards any leading whitespace characters when reading the next formatted input. Assuming you want to stick with using ss >> inBuffer
when grabbing input, you need to find someway to preemptively grab any leading whitespace before you perform any input extraction.
For example,
string eatwhite(const string &str, size_t pos)
{
size_t endwhite = str.find_first_not_of(" \t\n", pos);
if (endwhite == string::npos) return "";
return string(str.begin() + pos, str.begin() + endwhite);
}
Now you would call eatwhite
before doing any >>
:
string outBuffer = eatwhite(ss.str(), ss.tellg());
while (ss >> inBuffer)
{
for (auto keyIT : keywords)
{
//...
}
string whitesp = eatwhite(ss.str(), ss.tellg());
outBuffer += inBuffer + whitesp;
}
outFile << outBuffer << endl;
Upvotes: 1