如何从C++中的字符串中删除某些字符?

SD.*_*SD. 93 c++ string character

例如,我有一个用户输入电话号码.

cout << "Enter phone number: ";
INPUT: (555) 555-5555
cin >> phone;
Run Code Online (Sandbox Code Playgroud)

我想从字符串中删除"(",")"和" - "字符.我看了字符串删除,查找和替换功能但是我只看到它们根据位置操作.

是否有一个字符串函数,我可以用来传递一个字符,"(例如,并让它删除字符串中的所有实例?

Eri*_*c Z 132

   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;
Run Code Online (Sandbox Code Playgroud)

要用作功能:

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, "()-" );
Run Code Online (Sandbox Code Playgroud)

  • @Brent和未来的读者,这是[Erase-remove idiom](http://en.wikipedia.org/wiki/Erase-remove_idiom).简而言之,`std :: remove`将未删除的项移动到向量的前面,并返回一个指向超出最后一个未删除项的迭代器.然后`std :: erase`修剪从迭代器到结尾的向量. (11认同)
  • 这是如何运作的?使用擦除和删除不是双重否定吗?对我来说,这是:"擦除() - 不在的位置的字符." 既然每次都完成,不应该删除所有字符吗?我已经阅读了关于这两个函数的文档,这对我来说毫无意义.http://www.cplusplus.com/reference/algorithm/remove/ http://www.cplusplus.com/reference/string/string/erase/ (4认同)
  • 用作 **function:** http://ideone.com/XOROjq - 使用 `&lt;iostream&gt;` `&lt;algorithm&gt;` `&lt;cstring&gt;` (2认同)
  • 你最好缓存 `strlen(chars)` 因为它有 `O(n)` 复杂性 (2认同)

In *_*ico 35

我想从字符串中删除"(",")"和" - "字符.

您可以使用该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
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

您可以指定要使用"()- "字符串删除的字符.在上面的例子中,我添加了一个空格,以便删除空格以及括号和短划线.


Sha*_*531 12

remove_if()已被提及.但是,使用C++ 0x,您可以使用lambda为其指定谓词.

以下是使用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;
}
Run Code Online (Sandbox Code Playgroud)


小智 8

对于任何感兴趣的人来说,这是一个不同 它在c ++ 11中使用新的For range

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;
Run Code Online (Sandbox Code Playgroud)


Sto*_*yte 6

我担心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;
}
Run Code Online (Sandbox Code Playgroud)

编辑:阅读下面的答案,我理解它更一般,不仅检测数字.上述解决方案将省略第二个参数字符串中传递的每个字符.例如:

std::string result=RemoveChars("(999)99-8765-43.87", "()-");
Run Code Online (Sandbox Code Playgroud)

会导致

99999876543.87
Run Code Online (Sandbox Code Playgroud)


Cir*_*四事件 5

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"));
}
Run Code Online (Sandbox Code Playgroud)

在 Ubuntu 16.04、Boost 1.58 中测试。