Это похоже на работу для std::remove_if
:
auto new_end = std::remove_if(begin(s), end(s), [](char c)
{
return !isalpha(c);
});
// remove_if returns the new end, we need to erase from that to the old end
// (see the "erase-remove" idiom, https://en.wikipedia.org/wiki/Erase–remove_idiom)
s.erase(new_end, end(s));
Проблема с вашим текущим кодом заключается в том, что erase
изменяет Строка, по которой вы перебираете, и вы просто пропускаете (с it++
) следующий символ в строке.
Вам нужно использовать итератор, возвращаемый erase
в качестве следующего итератор для проверки:
for(auto it = s.begin(); it != s.end(); /* empty */)
{
if(!isalpha(*it))
it = s.erase(it);
else
++it;
}