Как удалить определенные символы из строки в C ++?

Например, у меня есть пользовательский номер телефона.

cout <> phone; 

Я хочу удалить символы «(», «)» и «-» из строки. Я посмотрел на строку удаления, поиска и замены функций, но я вижу только, что они работают в зависимости от позиции.

Есть ли строка-функция, которую я могу использовать для передачи символа? “(Например, и удалить все экземпляры в строке?

  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; 

Использовать как функцию :

 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, "()-" ); 

Я хочу удалить символы «(», «)» и «-» из строки.

Вы можете использовать алгоритм std::remove_if() для удаления только указанных вами символов:

 #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 } 

Алгоритм std::remove_if() требует чего-то, называемого предикатом, который может быть указателем на функцию, подобным приведенному выше fragmentу.

Вы также можете передать объект функции (объект, который перегружает оператор функции () ). Это позволяет нам создать еще более общее решение:

 #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 } 

Вы можете указать, какие символы удалить с помощью строки "()- " . В приведенном выше примере я добавил пробел, чтобы удалить пробелы, а также круглые скобки и тире.

remove_if () уже упоминалось. Но, с C ++ 0x, вы можете указать предикат для него с лямбдой вместо этого.

Ниже приведен пример этого с тремя различными способами фильтрации. «Копировать» версии функций также включены для случаев, когда вы работаете с константой или не хотите изменять оригинал.

 #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; } 

Вот другое решение для всех, кто интересуется. Он использует новый диапазон для диапазона в 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< 

Боюсь, что нет такого участника для std :: string, но вы можете легко запрограммировать такие функции. Это может быть не самое быстрое решение, но этого было бы достаточно:

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

EDIT: прочитав ответ ниже, я понял, что он более общий, а не только для определения цифры. Вышеупомянутое решение опускает каждый символ, переданный во второй строке аргумента. Например:

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

В результате

 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()); 

Примечание. Возможно, вам нужно написать ptr_fun а не просто ptr_fun

Да, вы можете использовать функцию isdigit () для проверки цифр 🙂

Ну вот:

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

Надеюсь, поможет 🙂

boost::is_any_of одного лайнера для полосы для всех символов из заданной строки:

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

Если у вас есть доступ к компилятору, который поддерживает вариативные шаблоны, вы можете использовать это:

 #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; } 

Вот еще одна альтернатива:

 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, "()-"); 

Работает с std :: string и std :: wstring

Я новичок, но некоторые из приведенных выше ответов безумно сложны, так что вот альтернатива.

ПРИМЕЧАНИЕ. Пока 0-9 смежны (что они должны соответствовать стандарту), это должно отфильтровывать все остальные символы, кроме цифр, и «». Знание 0-9 должно быть смежным, а char – это int, мы можем сделать следующее.

EDIT: Я тоже не заметил, что плакаты тоже нужны, поэтому я изменил его …

 #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; } 

Ниже приведен фильтр символов.

 #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; } 

Использование std :: wstring и wchar_t (требуется заголовок Unicode ):

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

… fancy static initial initializer next; не нужно настраивать badChars2 точно так же. Это перебор; более академичен, чем что-либо еще:

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

Простая, лаконичная lambda:

  1. Использует телефон в списке захвата лямбды.
  2. Использует Erase-remove idiom
  3. Удаляет все плохие персонажи с телефона

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

Выход: «555 5555555»

Для тех из вас, кто предпочитает более сжатый, более легкий для чтения стиль кодирования lambda …

В этом примере удаляются все символы, отличные от буквенно-цифровых и пробелов, из широкой строки. Вы можете смешивать его с любыми другими функциями ctype.h для удаления сложных визуальных тестов на основе символов.

(Я не уверен, как эти функции будут обрабатывать языки CJK, так что там спокойно ходите).

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

Посмотрите, не поняли ли вы, что это легче понять, чем шумные циклы C / C ++ for / iterator:

 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 после запуска этого кода: « 1ReplenMoveRPMV »

Это просто академично, поскольку было бы более четко, красно и эффективно комбинировать логику «if» от lambda0 (first for_each ) до единственного lambda1 (second for_each ), если вы уже установили, какие символы являются «badChars», ,

Давайте будем гением компьютера.