Почему последний символ удваивается, когда я стираю другие символы, и как мне это предотвратить? - PullRequest
2 голосов
/ 18 марта 2020

У меня есть следующий код:

auto rrr="my mixed string"s;
rrr.erase(std::remove_if(std::begin(rrr), std::end(rrr), [](char const c) { return c == 'm'; }));
std::cout<<rrr<<std::endl;

Вывод: y ixed stringg

Я ожидал, что код просто удалит все m в строке, вместо этого он также добавил g в конце

Почему это произошло и как я могу это исправить?

Ответы [ 2 ]

5 голосов
/ 18 марта 2020

Вы используете неправильную erase() перегрузку. Вы вызываете перегрузку erase(), которая принимает один параметр итератора, итератор для одного символа, который будет удален из строки.

std::remove_if «удаляет» значения из последовательности, просто перемещая их до конца, а затем возвращает новое значение итератора «окончание последовательности». Ваш неправильный перегруз erase() удаляет только символ после новой последовательности. Если бы ничего не было удалено, вы бы передали end() в erase(), что привело бы к неопределенному поведению и вероятному взлому sh. Но в этом случае вам повезло.

Чтобы полностью удалить «удаленные» символы, которые были перемещены в конец строки, передайте итератор строки end() в erase():

rrr.erase( /* What you already have */, rrr.end());

Ваша книга по С ++ или справочное руководство по С ++ должна иметь полный список всех доступных перегрузок erase(), включая тот, который вы должны были использовать здесь, и объяснение того, что они делают.

1 голос
/ 18 марта 2020

Или используйте версию Boost (если для вас доступно повышение), избегая всего вздутого кода.

boost::range::remove_erase_if(rrr, [](char c) { return c == 'm'; });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...