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

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

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

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

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

Ответы [ 13 ]

1 голос
/ 09 января 2014

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

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

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

    // Boring C loops: 'for(int i=0;i<str.size();i++)' 
    // Boring C++ eqivalent: 'for(iterator iter=c.begin; iter != c.end; ++iter)'

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

TSTRING label = _T("1.   Replen & Move  RPMV");
TSTRING newLabel = label;
set<TCHAR> 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 "

Это просто академический подход, поскольку было бы более точным, лаконичным и эффективным объединить логику «если» из lambda0 (первая for_each ) в одну лямбда1 (вторая for_each * 1020). *), если вы уже установили, какие символы являются «badChars».

1 голос
/ 12 февраля 2013

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

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

РЕДАКТИРОВАТЬ: Я не заметил, что на плакате тоже нужны пробелы, поэтому я изменил его ...

#include <cstdio>
#include <cstring>

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 <cstdio>
#include <cstring>

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;
}
1 голос
/ 16 ноября 2011

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

template<typename T>
void Remove( std::basic_string<T> & Str, const T * CharsToRemove )
{
    std::basic_string<T>::size_type pos = 0;
    while (( pos = Str.find_first_of( CharsToRemove, pos )) != std::basic_string<T>::npos )
    {
        Str.erase( pos, 1 ); 
    }
}

std::string a ("(555) 555-5555");
Remove( a, "()-");

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

...