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

例如,我有一个用户input一个电话号码。

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

我想从string中删除“(”,“)”和“ – ”字符。 我已经看了string删除,查找和replacefunction,但我只看到他们的立场的基础上运作。

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

  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; 

作为function使用:

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

我想从string中删除“(”,“)”和“ – ”字符。

您可以使用std::remove_if()algorithm仅删除您指定的字符:

 #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()algorithm需要一个谓词谓词,它可以像上面的代码片段那样是一个函数指针。

你也可以传递一个函数对象 (一个重载函数call ()运算符的对象)。 这使我们能够创build更加通用的解决scheme:

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

您可以使用"()- "string指定要删除的字符。 在上面的示例中,我添加了一个空格,以便删除空格以及括号和破折号。

remove_if()已经被提及。 但是,用C ++ 0x,你可以用lambda来指定它的谓词。

下面是以3种不同方式进行过滤的一个例子。 当你使用一个const或不想修改原始的情况下,也包括“复制”版本的function。

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

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

 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; 

恐怕没有std :: string这样的成员,但是你可以很容易地编写这样的函数。 这可能不是最快的解决scheme,但这样就足够了:

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

编辑:阅读下面的答案,我明白这是更一般的,不仅要检测数字。 上面的解决scheme将省略在第二个参数string中传递的每个字符。 例如:

 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<int, int>而不是简单的ptr_fun

是的,你可以使用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; } 

希望它有助于:)

boost::is_any_of一个class轮boost::is_any_of给定string中的所有字符:

 #include <boost/range/algorithm/remove_if.hpp> #include <boost/algorithm/string/classification.hpp> std::string str = "a_bc0_d"; str.erase(boost::remove_if(str, boost::is_any_of("_0")), str.end()); assert((str == "abcd")); 

如果您有权访问支持可变参数模板的编译器,则可以使用以下命令:

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

这是又一个select:

 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

我是新的,但上面的一些答案是非常复杂的,所以这里有一个select。

注意:只要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; } 

使用std :: wstringwchar_t (需要Unicode标头):

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

下一个花哨的静态范围初始化器; 没有必要以完全相同的方式设置badChars2。 这太过分了 比其他任何东西都学术:

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

简单,简洁的lambda:

  1. 在lambda捕获列表中使用电话
  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”

对于那些喜欢更简洁,更容易阅读lambda编码风格的人来说…

本示例从宽string中删除所有非字母数字和空格字符。 你可以把它与任何其他的ctype.h helper函数混合在一起,去除复杂外观的基于字符的testing。

(我不确定这些函数如何处理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 ++ for / iterator循环更容易理解:

 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

这只是理论上的,因为如果已经确定哪些字符是“badChars”,那么将lambda0(first for_each )中的“if”逻辑组合成单个lambda1(second for_each )会更加精确,简洁和高效。 。