I have a c++ string
with embedded '\0'
characters.
I have a function replaceAll()
which should replace all occurrences of a pattern with another pattern. For "normal" strings it works fine. However, when I try to find the '\0'
character my function does not work and I don't know why. replaceAll
seems to be failing on string::find()
which doesn't make sense to me.
// Replaces all occurrences of the text 'from' to the text 'to' in the specified input string.
// replaceAll("Foo123Foo", "Foo", "Bar"); // Bar123Bar
string replaceAll( string in, string from, string to )
{
string tmp = in;
if ( from.empty())
{
return in;
}
size_t start_pos = 0;
// tmp.find() fails to match on "\0"
while (( start_pos = tmp.find( from, start_pos )) != std::string::npos )
{
tmp.replace( start_pos, from.length(), to );
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}
return tmp;
}
int main(int argc, char* argv[])
{
string stringWithNull = { '\0', '1', '\0', '2' };
printf("size=[%d] data=[%s]\n", stringWithNull.size(), stringWithNull.c_str());
// This doesn't work in the special case of a null character and I don't know why
string replaced = replaceAll(stringWithNull, "\0", "");
printf("size=[%d] data=[%s]\n", replaced.size(), replaced.c_str());
}
Output:
size=[4] data=[]
size=[4] data=[]
The reason why it doesn't work in your case is that std::string
constructor from const char*
without size is going to read all elements up to, but not including nul-terminating char. As a result,
replaceAll(stringWithNull, "\0", "");
Calls replaceAll
with from
set to empty string (replaceAll( string in, string from, string to )
), which returns in
unmodified.
To solve the problem, use a constructor which takes size, or initialize with list initialization, the same way you do it for your original string, for example:
replaceAll(stringWithNull, {'\0'}, "");