簡體   English   中英

C++ 從字符串中刪除標點符號

[英]C++ Remove punctuation from String

我有一個字符串,我想從中刪除所有標點符號。 我該怎么做? 我做了一些研究,發現人們使用 ispunct() 函數(我試過了),但我似乎無法讓它在我的代碼中工作。 有人有任何想法嗎?

#include <string>

int main() {

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

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

return 0;
}

使用算法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)  
                       );

如果您需要將結果作為新字符串,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 (可能還有一些我暫時忘記的其他算法庫函數)采用這種方法來關閉它們刪除的項目的間隙,但將容器調整大小留給來電者。

#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

刪除字符時,字符串的大小會發生變化。 每當發生刪除時都必須更新它。 並且,您刪除了當前字符,因此下一個字符成為當前字符。 如果不減少循環計數器,則不會檢查標點字符旁邊的字符。

ispunct采用char值而不是字符串。

你可以喜歡

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

這會起作用,但它是一種緩慢的算法。

這里的問題是 ispunct() 將一個參數作為一個字符,而您正在嘗試發送一個字符串。 您應該遍歷字符串的元素並刪除每個字符,如果它是像這里這樣的標點符號:

for(size_t i = 0; i<text.length(); ++i)
  if(ispunct(text[i]))
    text.erase(i--, 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;
    });
}

Steve314 的回答非常好。 我想添加一個小改動:

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

在函數 ispunct 之前添加 :: 負責重載。

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

您可以執行此操作的另一種方法如下:

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

這最終會創建一個新字符串,而不是實際刪除舊字符串中的字符,但與使用一些更復雜的內置函數相比,繞起來要容易一些。

嘗試使用這個,它會刪除文本文件中字符串上的所有標點符號 ok。

str.erase(remove_if(str.begin(), str.end(), ::ispunct), str.end());

如果有幫助請回復

我試圖申請@ Steve314的答案,但它不能去工作,直到我碰到這個筆記來到這里的cppreference.com:

筆記

與來自<cctype>所有其他函數一樣,如果參數的值既不能表示為unsigned char也不等於 EOF,則std::ispunct的行為是未定義的。 要安全地將這些函數與普通char (或有signed char )一起使用,應首先將參數轉換為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;
}

我明白了。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM