Как удалить определенные символы из строки в C ++? - PullRequest
92 голосов
/ 05 мая 2011

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

cout << "Enter phone number: ";
INPUT: (555) 555-5555
cin >> phone;

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

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

Ответы [ 13 ]

128 голосов
/ 05 мая 2011
   string str("(555) 555-5555");

   char chars[] = "()-";

   for (unsigned int i = 0; i < strlen(chars); ++i)
   {
      // you need include <algorithm> 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, "()-" );
35 голосов
/ 05 мая 2011

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

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

#include <iostream>
#include <algorithm>
#include <string>

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() требует чего-то, называемого предикатом, который может быть указателем на функцию, подобным приведенному выше фрагменту.

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

#include <iostream>
#include <algorithm>
#include <string>

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
}

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

12 голосов
/ 05 мая 2011

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

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

#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
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;
}
8 голосов
/ 07 мая 2013

Вот другое решение для всех, кто заинтересован.Он использует новый диапазон For в 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<<str<<endl;
6 голосов
/ 05 мая 2011

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

std::string RemoveChars(const std::string& source, const std::string& chars) {
   std::string result="";
   for (unsigned int i=0; i<source.length(); i++) {
      bool foundany=false;
      for (unsigned int j=0; j<chars.length() && !foundany; j++) {
         foundany=(source[i]==chars[j]);
      }
      if (!foundany) {
         result+=source[i];
      }
   }
   return result;
}

РЕДАКТИРОВАТЬ: Читая ответ ниже, я понял, что это более общий, а не только для обнаружения цифры.Приведенное выше решение будет пропускать каждый символ, переданный во второй строке аргумента.Например:

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

приведет к

99999876543.87
4 голосов

boost::is_any_of

Убрать все символы из одной строки, которые появляются в другой заданной строке:

#include <cassert>

#include <boost/range/algorithm/remove_if.hpp>
#include <boost/algorithm/string/classification.hpp>

int main() {
    std::string str = "a_bc0_d";
    str.erase(boost::remove_if(str, boost::is_any_of("_0")), str.end());
    assert((str == "abcd"));
}

Протестировано в Ubuntu 16.04, Boost 1.58.

4 голосов
/ 28 мая 2013
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<int, int> вместо простого ptr_fun

3 голосов
/ 05 мая 2011

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

А вот и вы:

#include <iostream>
#include <cctype>
#include <string.h>

using namespace std;

int main(){

  char *str = "(555) 555-5555";
  int len = strlen(str);

  for (int i=0; i<len; i++){
      if (isdigit(*(str+i))){
        cout << *(str+i);
      }
  }

  cout << endl;


return 0;   
}

Надеюсь, это поможет:)

2 голосов
/ 05 мая 2011

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

#include <iostream>
#include <string>
#include <algorithm>

template<char ... CharacterList>
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<char ... CharacterList>
inline void strip_characters(std::string & str) {
    str.erase(std::remove_if(str.begin(), str.end(), &check_characters<CharacterList...>), str.end());
}

int main()
{
    std::string str("(555) 555-5555");
    strip_characters< '(',')','-' >(str);
    std::cout << str << std::endl;
}
1 голос
/ 09 января 2014

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

//#include <tchar.h>
std::wstring phone(L"(555) 555-5555");

... необычный инициализатор статического диапазона next; не нужно настраивать badChars2 таким же образом. Это излишне; более академичный, чем все остальное:

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

Простая, краткая лямбда:

  1. Использует телефон в списке лямбда-захвата.
  2. Использование Стирание-удаление идиома
  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"

...