¿Cómo eliminar ciertos caracteres de una cadena en C ++?

Por ejemplo, tengo un usuario que ingresa un número de teléfono.

cout <> phone; 

Quiero eliminar los caracteres “(“, “)” y “-” de la cadena. He observado las funciones de extracción, búsqueda y reemplazo de cadenas, pero solo veo que operan en función de la posición.

¿Hay una función de cadena que pueda usar para pasar un carácter “(” por ejemplo, y que elimine todas las instancias dentro de una cadena?

  string str("(555) 555-5555"); char chars[] = "()-"; for (unsigned int i = 0; i < strlen(chars); ++i) { // you need include  to use general algorithms like std::remove() str.erase (std::remove(str.begin(), str.end(), chars[i]), str.end()); } // output: 555 5555555 cout << str << endl; 

Para usar como función :

 void removeCharsFromString( string &str, char* charsToRemove ) { for ( unsigned int i = 0; i < strlen(charsToRemove); ++i ) { str.erase( remove(str.begin(), str.end(), charsToRemove[i]), str.end() ); } } //example of usage: removeCharsFromString( str, "()-" ); 

Quiero eliminar los caracteres “(“, “)” y “-” de la cadena.

Puede usar el algoritmo std::remove_if() para eliminar solo los caracteres que especifique:

 #include  #include  #include  bool IsParenthesesOrDash(char c) { switch(c) { case '(': case ')': case '-': return true; default: return false; } } int main() { std::string str("(555) 555-5555"); str.erase(std::remove_if(str.begin(), str.end(), &IsParenthesesOrDash), str.end()); std::cout << str << std::endl; // Expected output: 555 5555555 } 

El algoritmo std::remove_if() requiere algo llamado predicado, que puede ser un puntero de función como el fragmento anterior.

También puede pasar un objeto de función (un objeto que sobrecarga el operador de llamada de función). Esto nos permite crear una solución aún más general:

 #include  #include  #include  class IsChars { public: IsChars(const char* charsToRemove) : chars(charsToRemove) {}; bool operator()(char c) { for(const char* testChar = chars; *testChar != 0; ++testChar) { if(*testChar == c) { return true; } } return false; } private: const char* chars; }; int main() { std::string str("(555) 555-5555"); str.erase(std::remove_if(str.begin(), str.end(), IsChars("()- ")), str.end()); std::cout << str << std::endl; // Expected output: 5555555555 } 

Puede especificar qué caracteres eliminar con la cadena "()- " . En el ejemplo anterior, agregué un espacio para que se eliminen espacios, así como paréntesis y guiones.

remove_if () ya ha sido mencionado. Pero, con C ++ 0x, puede especificar el predicado para él con una lambda en su lugar.

A continuación se muestra un ejemplo de eso con 3 formas diferentes de hacer el filtrado. Las versiones de “copia” de las funciones también se incluyen para casos en los que esté trabajando con un const o no desee modificar el original.

 #include  #include  #include  #include  using namespace std; string& remove_chars(string& s, const string& chars) { s.erase(remove_if(s.begin(), s.end(), [&chars](const char& c) { return chars.find(c) != string::npos; }), s.end()); return s; } string remove_chars_copy(string s, const string& chars) { return remove_chars(s, chars); } string& remove_nondigit(string& s) { s.erase(remove_if(s.begin(), s.end(), [](const char& c) { return !isdigit(c); }), s.end()); return s; } string remove_nondigit_copy(string s) { return remove_nondigit(s); } string& remove_chars_if_not(string& s, const string& allowed) { s.erase(remove_if(s.begin(), s.end(), [&allowed](const char& c) { return allowed.find(c) == string::npos; }), s.end()); return s; } string remove_chars_if_not_copy(string s, const string& allowed) { return remove_chars_if_not(s, allowed); } int main() { const string test1("(555) 555-5555"); string test2(test1); string test3(test1); string test4(test1); cout << remove_chars_copy(test1, "()- ") << endl; cout << remove_chars(test2, "()- ") << endl; cout << remove_nondigit_copy(test1) << endl; cout << remove_nondigit(test3) << endl; cout << remove_chars_if_not_copy(test1, "0123456789") << endl; cout << remove_chars_if_not(test4, "0123456789") << endl; } 

Aquí hay una solución diferente para cualquier persona interesada. Utiliza el nuevo rango For en c ++ 11

 string str("(555) 555-5555"); string str2=""; for (const auto c: str){ if(!ispunct(c)){ str2.push_back(c); } } str = str2; //output: 555 5555555 cout< 

Me temo que no existe tal miembro para std :: string, pero puede progtwigr fácilmente ese tipo de funciones. Puede que no sea la solución más rápida, pero esto sería suficiente:

 std::string RemoveChars(const std::string& source, const std::string& chars) { std::string result=""; for (unsigned int i=0; i 

EDITAR: Al leer la respuesta a continuación, entendí que era más general, no solo para detectar dígitos. La solución anterior omitirá cada carácter pasado en la segunda cadena de argumento. Por ejemplo:

 std::string result=RemoveChars("(999)99-8765-43.87", "()-"); 

Resultará en

 99999876543.87 
 using namespace std; // c++03 string s = "(555) 555-5555"; s.erase(remove_if(s.begin(), s.end(), not1(ptr_fun(::isdigit))), s.end()); // c++11 s.erase(remove_if(s.begin(), s.end(), ptr_fun(::ispunct)), s.end()); 

Nota: Es posible que necesite escribir ptr_fun lugar de simple ptr_fun

Sí, puede usar la función isdigit () para verificar si hay dígitos 🙂

Aqui tienes:

 #include  #include  #include  using namespace std; int main(){ char *str = "(555) 555-5555"; int len = strlen(str); for (int i=0; i 

Espero eso ayude 🙂

boost::is_any_of one liner para despojar a todos los personajes de una cadena dada:

 #include  #include  std::string str = "a_bc0_d"; str.erase(boost::remove_if(str, boost::is_any_of("_0")), str.end()); assert((str == "abcd")); 

Si tiene acceso a un comstackdor que admita plantillas variadic, puede usar esto:

 #include  #include  #include  template inline bool check_characters(char c) { char match_characters[sizeof...(CharacterList)] = { CharacterList... }; for(int i = 0; i < sizeof...(CharacterList); ++i) { if(c == match_characters[i]) { return true; } } return false; } template inline void strip_characters(std::string & str) { str.erase(std::remove_if(str.begin(), str.end(), &check_characters), str.end()); } int main() { std::string str("(555) 555-5555"); strip_characters< '(',')','-' >(str); std::cout << str << std::endl; } 

Aquí hay otra alternativa:

 template void Remove( std::basic_string & Str, const T * CharsToRemove ) { std::basic_string::size_type pos = 0; while (( pos = Str.find_first_of( CharsToRemove, pos )) != std::basic_string::npos ) { Str.erase( pos, 1 ); } } std::string a ("(555) 555-5555"); Remove( a, "()-"); 

Funciona con std :: string y std :: wstring

Soy nuevo, pero algunas de las respuestas anteriores son increíblemente complicadas, así que aquí hay una alternativa.

NOTA: Mientras 0-9 sean contiguos (que deberían estar de acuerdo con el estándar), esto debería filtrar todos los demás caracteres, excepto los números y ”. Sabiendo que 0-9 debe ser contiguo y un char es realmente un int, podemos hacer lo siguiente.

EDITAR: No me di cuenta de que el póster también quería espacios, así que lo modifiqué …

 #include  #include  void numfilter(char * buff, const char * string) { do { // According to standard, 0-9 should be contiguous in system int value. if ( (*string >= '0' && *string <= '9') || *string == ' ') *buff++ = *string; } while ( *++string ); *buff++ = '\0'; // Null terminate } int main() { const char *string = "(555) 555-5555"; char buff[ strlen(string) + 1 ]; numfilter(buff, string); printf("%s\n", buff); return 0; } 

Debajo está para filtrar los caracteres suministrados.

 #include  #include  void cfilter(char * buff, const char * string, const char * toks) { const char * tmp; // So we can keep toks pointer addr. do { tmp = toks; *buff++ = *string; // Assume it's correct and place it. do // I can't think of a faster way. { if (*string == *tmp) { buff--; // Not correct, pull back and move on. break; } }while (*++tmp); }while (*++string); *buff++ = '\0'; // Null terminate } int main() { char * string = "(555) 555-5555"; char * toks = "()-"; char buff[ strlen(string) + 1 ]; cfilter(buff, string, toks); printf("%s\n", buff); return 0; } 

Usando std :: wstring y wchar_t (requiere el encabezado Unicode ):

 //#include  std::wstring phone(L"(555) 555-5555"); 

… elegante inicializador de rango estático siguiente; no es necesario configurar badChars2 de la misma manera. Es excesivo; más académico que cualquier otra cosa:

 const wchar_t *tmp = L"()-"; const std::set badChars2(tmp,tmp + sizeof(tmp)-1); 

Lambda simple y conciso:

  1. Utiliza el teléfono en la lista de captura lambda.
  2. Utiliza la expresión de borrar-eliminar
  3. Elimina todos los caracteres malos del teléfono

     for_each(badChars2.begin(), badChars2.end(), [&phone](wchar_t n){ phone.erase(std::remove(phone.begin(), phone.end(), n), phone.end()); }); wcout << phone << endl; 

Salida: "555 5555555"

Para aquellos de ustedes que prefieren un estilo de encoding lambda más conciso y fácil de leer …

Este ejemplo elimina todos los caracteres de espacios en blanco y no alfanuméricos de una cadena ancha. Puede mezclarlo con cualquiera de las otras funciones auxiliares ctype.h para eliminar las pruebas basadas en caracteres de aspecto complejo.

(No estoy seguro de cómo estas funciones manejarían los lenguajes CJK, así que camine suavemente allí).

  // Boring C loops: 'for(int i=0;i 

Vea si no encuentra esto más fácil de entender que los ruidosos C / C ++ for / iterator loops:

 TSTRING label = _T("1. Replen & Move RPMV"); TSTRING newLabel = label; set badChars; // Use ispunct, isalpha, isdigit, et.al. (lambda version, with capture list parameter(s) example; handiest thing since sliced bread) for_each(label.begin(), label.end(), [&badChars](TCHAR n){ if (!isalpha(n) && !isdigit(n)) badChars.insert(n); }); for_each(badChars.begin(), badChars.end(), [&newLabel](TCHAR n){ newLabel.erase(std::remove(newLabel.begin(), newLabel.end(), n), newLabel.end()); }); 

newLabel resultados después de ejecutar este código: " 1ReplenMoveRPMV "

Esto es solo académico, ya que sería claramente más preciso, conciso y eficiente combinar la lógica 'si' de lambda0 (primero para cada uno ) en la única lambda1 (segunda para cada uno ), si ya ha establecido qué caracteres son los "badChars" .