C++ 如何从C++中的字符串中删除某些字符?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5891610/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to remove certain characters from a string in C++?
提问by SD.
For example I have a user input a phone number.
例如我有一个用户输入一个电话号码。
cout << "Enter phone number: ";
INPUT: (555) 555-5555
cin >> phone;
I want to remove the "(", ")", and "-" characters from the string. I've looked at the string remove, find and replace functions however I only see that they operate based on position.
我想从字符串中删除“(”、“)”和“-”字符。我看过字符串删除、查找和替换函数,但是我只看到它们基于位置进行操作。
Is there a string function that I can use to pass a character, "(" for example, and have it remove all instances within a string?
是否有一个字符串函数可以用来传递一个字符,例如“(”,并让它删除一个字符串中的所有实例?
回答by Eric Z
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;
To use as 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, "()-" );
回答by In silico
I want to remove the "(", ")", and "-" characters from the string.
我想从字符串中删除“(”、“)”和“-”字符。
You can use the std::remove_if()
algorithm to remove only the characters you specify:
您可以使用该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
}
The std::remove_if()
algorithm requires something called a predicate, which can be a function pointer like the snippet above.
该std::remove_if()
算法需要一个称为谓词的东西,它可以是一个函数指针,就像上面的代码片段一样。
You can also pass a function object(an object that overloads the function call ()
operator). This allows us to create an even more general solution:
您还可以传递函数对象(重载函数调用()
运算符的对象)。这使我们能够创建一个更通用的解决方案:
#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
}
You can specify what characters to remove with the "()- "
string. In the example above I added a space so that spaces are removed as well as parentheses and dashes.
您可以指定要使用"()- "
字符串删除的字符。在上面的示例中,我添加了一个空格,以便删除空格以及括号和破折号。
回答by Shadow2531
remove_if() has already been mentioned. But, with C++0x, you can specify the predicate for it with a lambda instead.
remove_if() 已经被提及。但是,对于 C++0x,您可以使用 lambda 为其指定谓词。
Below is an example of that with 3 different ways of doing the filtering. "copy" versions of the functions are included too for cases when you're working with a const or don't want to modify the original.
下面是使用 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;
}
回答by ashwin911
Here is a different solution for anyone interested. It uses the new For range in c++11
对于任何感兴趣的人,这是一个不同的解决方案。它在 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;
回答by StormByte
I'm afraid there is no such a member for std::string, but you can easily program that kind of functions. It may not be the fastest solution but this would suffice:
恐怕 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;
}
EDIT: Reading the answer below, I understood it to be more general, not only to detect digit. The above solution will omit every character passed in the second argument string. For example:
编辑:阅读下面的答案,我理解它更通用,不仅仅是检测数字。上述解决方案将省略在第二个参数字符串中传递的每个字符。例如:
std::string result=RemoveChars("(999)99-8765-43.87", "()-");
Will result in
会导致
99999876543.87
回答by Oleg Svechkarenko
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());
Note:It's posible you need write ptr_fun<int, int>
rather than simple ptr_fun
注意:您可能需要编写ptr_fun<int, int>
而不是简单ptr_fun
回答by Vern
Yes, you can use the isdigit() function to check for a digits :)
是的,您可以使用 isdigit() 函数来检查数字:)
Here you go:
干得好:
#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;
}
Hope it helps :)
希望能帮助到你 :)
回答by Timesquare
If you have access to a compiler that supports variadic templates, you can use this:
如果您有权访问支持可变参数模板的编译器,则可以使用以下命令:
#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;
}
回答by Jem
Here's yet another alternative:
这是另一种选择:
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, "()-");
Works with std::string and std::wstring
适用于 std::string 和 std::wstring
回答by JustTired
I'm new, but some of the answers above are insanely complicated, so here's an alternative.
我是新手,但上面的一些答案非常复杂,所以这里有一个替代方案。
NOTE: As long as 0-9 are contiguous (which they should be according to the standard), this should filter out all other characters but numbers and ' '. Knowing 0-9 should be contiguous and a char is really an int, we can do the below.
注意:只要 0-9 是连续的(它们应该根据标准),这应该过滤掉除数字和 ' ' 之外的所有其他字符。知道 0-9 应该是连续的,并且 char 确实是一个 int,我们可以执行以下操作。
EDIT: I didn't notice the poster wanted spaces too, so I altered it...
编辑:我没有注意到海报也想要空格,所以我改变了它......
#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++ = '#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++ = '##代码##'; // 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;
}
'; // Null terminate
}
int main()
{
const char *string = "(555) 555-5555";
char buff[ strlen(string) + 1 ];
numfilter(buff, string);
printf("%s\n", buff);
return 0;
}
Below is to filter supplied characters.
下面是过滤提供的字符。
##代码##