Удалить нулевой символ, встроенный в строку - PullRequest
0 голосов
/ 07 ноября 2018

У меня есть c ++ string со встроенными '\0' символами.

У меня есть функция 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=[]

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Когда вы делаете

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

"\0" - это то же самое, что и "", поскольку конструктор std::string останавливается на нулевом символе при построении из c-строки. Это означает, что вы ничего не ищете и не заменяете его ничем. Что вам нужно, это

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

для фактического заполнения from нулевым символом.

0 голосов
/ 07 ноября 2018

Причина, по которой это не работает в вашем случае, заключается в том, что конструктор std::string из const char* без размера будет читать все элементы вплоть до, но не включая nul-terminating char. В результате

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

Вызывает replaceAll с from, установленным в пустую строку (replaceAll( string in, string from, string to )), которая возвращает in без изменений.

Чтобы решить проблему, используйте конструктор, который принимает размер, или инициализируйте с помощью инициализации списка, так же, как вы делаете это для исходной строки, например:

replaceAll(stringWithNull, {'\0'}, "");
...