Я думаю для этого я бы использовал std::remove_copy_if
:
#include <string>
#include <algorithm>
#include <iostream>
struct bad_char {
bool operator()(char ch) {
return ch == '@' || ch == '#' || ch == '$' || ch == '%';
}
};
int main() {
std::string in("This@is#a$string%with@extra#stuff$to%ignore");
std::string out;
std::remove_copy_if(in.begin(), in.end(), std::back_inserter(out), bad_char());
std::cout << out << "\n";
return 0;
}
Результат:
Thisisastringwithextrastufftoignore
Поскольку данные, содержащие эти нежелательные символы, обычно поступают из какого-либо файла, также стоит подумать об их удалении, когда вы читаете данные из файла вместо чтения ненужных данных в строку, и затем отфильтровывает его. Для этого вы можете создать фасет, который классифицирует нежелательные символы как пробел:
struct filter: std::ctype<char>
{
filter(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table()
{
static std::vector<std::ctype_base::mask>
rc(std::ctype<char>::table_size,std::ctype_base::mask());
rc['@'] = std::ctype_base::space;
rc['#'] = std::ctype_base::space;
rc['$'] = std::ctype_base::space;
rc['%'] = std::ctype_base::space;
return &rc[0];
}
};
Чтобы использовать это, вы наполняете входной поток локалью, используя этот фасет, а затем читаете как обычно. На данный момент я буду использовать istringstream
, хотя вы обычно используете что-то вроде istream
или ifstream
:
int main() {
std::istringstream in("This@is#a$string%with@extra#stuff$to%ignore");
in.imbue(std::locale(std::locale(), new filter));
std::copy(std::istream_iterator<char>(in),
std::istream_iterator<char>(),
std::ostream_iterator<char>(std::cout));
return 0;
}