Creo que para este que haría uso de 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("[email protected]#a$string%[email protected]#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;
}
Resultado:
Thisisastringwithextrastufftoignore
Dado que los datos que contienen estos caracteres no deseados normalmente provienen de un archivo de algún tipo, también vale la pena considerarlos ng deshacerse de ellos mientras lee los datos del archivo en lugar de leer los datos no deseados en una cadena, y luego filtrándolo. Para ello, se podría crear una faceta que clasifica los caracteres no deseados como el espacio en blanco:
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];
}
};
a usar esto, Imbuyes el flujo de entrada con una configuración regional utilizando esta faceta, y luego lee normalmente. Por el momento voy a utilizar un istringstream
, aunque normalmente tendría que utilizar algo así como un istream
o ifstream
:
int main() {
std::istringstream in("[email protected]#a$string%[email protected]#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;
}
Dado que estamos hablando de una cadena, que voy a que te refieres a C++, y voy a volver a etiquetar se como tal. – James
Una cadena significa lo mismo en C también. –
@James: Realmente no creo que puedas hacer esa suposición. – Vicky