C ++从String中删除标点符号

时间:2013-10-02 14:10:43

标签: c++ string parsing erase punctuation

我有一个字符串,我想删除它的所有标点符号。我怎么做?我做了一些研究,发现人们使用ispunct()函数(我试过),但我似乎无法让它在我的代码中工作。有人有任何想法吗?

#include <string>

int main() {

string text = "this. is my string. it's here."

if (ispunct(text))
text.erase();

return 0;
}

12 个答案:

答案 0 :(得分:21)

使用算法remove_copy_if: -

string text,result;
std::remove_copy_if(text.begin(), text.end(),            
                        std::back_inserter(result), //Store output           
                        std::ptr_fun<int, int>(&std::ispunct)  
                       );

答案 1 :(得分:13)

如果您需要将结果作为新字符串,POW已经有了一个很好的答案。如果您想要就地更新,那么这个答案就是如何处理它。

配方的第一部分是std::remove_if,它可以有效地删除标点符号,包含所有非标点符号。

std::remove_if (text.begin (), text.end (), ispunct)

不幸的是,std::remove_if不会将字符串缩小到新大小。它不能,因为它无法访问容器本身。因此,在打包结果之后,字符串中会留下垃圾字符。

为了处理这个问题,std::remove_if返回一个迭代器,指示仍然需要的字符串部分。这可以与字符串erase方法一起使用,从而导致以下习语...

text.erase (std::remove_if (text.begin (), text.end (), ispunct), text.end ());

我称之为成语,因为它是一种在许多情况下都适用的常用技术。除了string之外的其他类型提供了合适的erase方法,而std::remove(以及可能暂时忘记的其他一些算法库函数)采用这种方法来缩小它们删除的项目的间隙,但将容器大小调整留给调用者。

答案 2 :(得分:4)

ispunctchar值而不是字符串。

你可以这样做

for (auto c : string)
     if (ispunct(c)) text.erase(text.find_first_of(c));

这将有效,但它是一种缓慢的算法。

答案 3 :(得分:4)

#include <string>
#include <iostream>
#include <cctype>

int main() {

    std::string text = "this. is my string. it's here.";

    for (int i = 0, len = text.size(); i < len; i++)
    {
        if (ispunct(text[i]))
        {
            text.erase(i--, 1);
            len = text.size();
        }
    }

    std::cout << text;
    return 0;
}

<强>输出

this is my string its here

删除字符时,字符串的大小会发生变化。每当发生删除时都必须更新它。并且,您删除了当前字符,因此下一个字符将成为当前字符。如果不减少循环计数器,则不会检查标点符号旁边的字符。

答案 4 :(得分:1)

这里的问题是,当你尝试发送一个字符串时,ispunct()将一个参数作为一个字符。你应该遍历字符串的元素并删除每个字符,如果它是一个标点符号,如下所示:

for(size_t i = 0; i<text.length(); ++i)
  if(ispunct(text[i]))
    text.erase(i--, 1);

答案 5 :(得分:1)

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main() {
    string str = "this. is my string. it's here.";

    transform(str.begin(), str.end(), str.begin(), [](char ch)
    {
        if( ispunct(ch) )
            return '\0';
        return ch;
    });
}

答案 6 :(得分:1)

Steve314的回答很好。 我想添加一个小的更改:

text.erase (std::remove_if (text.begin (), text.end (), ::ispunct), text.end ());

在函数ispunct之前添加::可以避免重载。

答案 7 :(得分:0)

 #include <iostream>
 #include <string>

 using namespace std;

 int main()
 {
   string s;//string is defined here.

  cout << "Please enter a string with punctuation's: " << endl;//Asking for users input

  getline(cin, s);//reads in a single string one line at a time

/* ERROR Check: The loop didn't run at first because a semi-colon was placed at the end 
                of the statement.  Remember not to add it for loops. */
        for(auto &c : s)  //loop checks every character 
        {       
             if (ispunct(c)) //to see if its a punctuation
              {
               c=' ';       //if so it replaces it with a blank space.(delete) 
              }

        }

        cout <<  s << endl; 


   system("pause");
   return 0;
   }

答案 8 :(得分:0)

另一种方法是:

#include <ctype.h> //needed for ispunct()
string onlyLetters(string str){
    string retStr = "";

    for(int i = 0; i < str.length(); i++){
        if(!ispunct(str[i])){
            retStr += str[i];
        }
    }
    return retStr;

这最终会创建一个新字符串而不是实际删除旧字符串中的字符,但是比使用一些更复杂的内置函数更容易包围。

答案 9 :(得分:0)

尝试使用这个,它将删除文本文件中的字符串上的所有标点符号。 str.erase(remove_if(str.begin(),str.end(),:: ispunct),str.end());

如果有帮助请回复

答案 10 :(得分:0)

我尝试应用@ Steve314的答案,但是直到我在cppreference.com上遇到此说明here时,它才能起作用:

  

注释

     

<cctype>中的所有其他功能一样,std::ispunct的行为   如果参数值既不能表示为,则不确定   unsigned char也不等于EOF。为了安全地使用这些功能   普通char s(或signed char s)中,参数应首先转换   到unsigned char

通过研究它提供的示例,我可以使它像这样工作:

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

int main()
{
    std::string text = "this. is my string. it's here.";
    std::string result;
    text.erase(std::remove_if(text.begin(),
                              text.end(),
                              [](unsigned char c) { return std::ispunct(c); }),
               text.end());
    std::cout << text << std::endl;
}

答案 11 :(得分:-3)

我明白了。

size_t found = text.find('.');
text.erase(found, 1);