The lines:
content.replace(content.begin(), content.end(), "<section />", "<section></section>");
content.replace(content.begin(), content.end(), "\t", "");
result in undefined behavior. They match the function:
template<class InputIterator>
std::string& std::string::replace(
const_iterator i1, const_iterator i2,
InputIterator j1, InputIterator j2);
with InputIterator
resolving to char const*
. The problem is
that the distance between the two iterators, and whether the
second can be reached from the first, is undefined, since they
point to totally unrelated bits of memory.
From your code, I don't think you understand what
std::string::replace
does. It replaces the range [i1,i2)
in
the string with the text defined by the range [j1,j2)
. It
does not do any search and comparison; it is for use after
you have found the range which needs replacing. Calling:
content.replace(content.begin(), content.end(), "<section />", "<section></section>");
has exactly the same effect as:
content = std::string( "<section />", "<section></section>");
, which is certainly not what you want.
In C++11, there's a regex_replace
function which may be of
some use, although if you're really doing this on very large
strings, it may not be the most performant (the added
flexibility of regular expressions comes at a price); I'd
probably use something like:
std::string
searchAndReplace(
std::string const& original,
std::string const& from,
std::string const& to)
{
std::string results;
std::string::const_iterator current = original.begin();
std::string::const_iterator end = original.end();
std::string::const_iterator next = std::search( current, end, from.begin(), from.end() );
while ( next != end ) {
results.append( current, next );
results.append( to );
current = next + from.size();
next = std::search( current, end, from.begin(), from.end() );
}
results.append( current, next );
return results;
}
For very large strings, some heuristic for guessing the size,
and then doing a reserve
on results
is probably a good idea
as well.
Finally, since your second line just removes '\t'
, you'd be
better off using std::remove
:
content.erase( std::remove( content.begin(), content.end(), '\t' ), content.end() );