1

我有一个string带有嵌入'\0'字符的 c++。

我有一个函数replaceAll()应该另一个模式替换所有出现的模式。对于“普通”字符串,它工作正常。但是,当我尝试查找'\0'角色时,我的功能不起作用,我不知道为什么。replaceAll似乎失败了,string::find()这对我来说没有意义。

// 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());
}

输出:

size=[4] data=[]
size=[4] data=[]
4

2 回答 2

6

它在您的情况下不起作用的原因是没有大小的std::string构造函数const char*将读取所有元素,但不包括 nul 终止字符。因此,

 replaceAll(stringWithNull, "\0", "");

设置为空字符串 ( ) 的调用replaceAll,返回未修改。fromreplaceAll( string in, string from, string to )in

为了解决这个问题,使用一个构造函数,它需要大小,或者使用列表初始化进行初始化,就像你对原始字符串做的那样,例如:

replaceAll(stringWithNull, {'\0'}, "");
于 2018-11-07T15:51:20.703 回答
1

When you do

replaceAll(stringWithNull, "\0", "");

"\0" is the same as "" since std::string's constructor stops at the null character when being constructed from a c-string. That means you are searching for nothing and replacing it with nothing. What you need is

string replaced = replaceAll(stringWithNull, {'\0'}, "");

to actually get from populated with a null character.

于 2018-11-07T15:55:14.037 回答