2013-10-02 398 views
10

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

#include <string> 

int main() { 

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

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

return 0; 
} 
+0

您應該逐個檢查所有字符。 –

回答

-3

我得到它。

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

這隻會刪除'。'的第一個實例,它不會刪除所有標點符號,也不會刪除所有'。'實例。 – pippin1289

+0

但與for循環它的工作 – NewFile

+0

你應該編輯你的答案,不要誤導別人。但它也只能刪除'。'。不是所有的標點符號。 – pippin1289

5

ispunct需要一個char值不是字符串。

你可以像

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

這會工作,但它是一個緩慢的算法。

+3

text.erase()?你確定? –

+1

你讓我了。 'text.erase()'不起作用。 –

1

這裏的問題是ispunct()將一個參數作爲一個字符,而您試圖發送一個字符串。你應該在字符串中的元素循環和擦除每個字符如果是喜歡這裏的標點符號:

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

當你刪除一個字符,大小字符串改變。只要發生刪除,它就必須更新。並且,您刪除了當前字符,所以下一個字符變成當前字符。如果您不減少循環計數器,則不會檢查標點符號旁邊的字符。

+0

我不能得到ispunct編譯。我已經包括了你所做的所有標題。 – NewFile

+1

您必須包含''或''。 – thefourtheye

19

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

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

[編輯 - 我不能相信我只是得到了不正確的 - 迭代器erase應說明的範圍內刪除,而不是保留的範圍。]

我稱之爲成語,因爲它是一種常用技術,適用於許多情況。除string之外的其他類型提供合適的erase方法,並且std::remove(以及可能還有一些我暫時忘記的其他算法庫函數)採用這種方法來關閉它們刪除的項目的間隙,但將容器調整大小留給調用者。

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

這最終建立一個新的字符串,而不是真正從舊字符串刪除字符,但它是一個更容易一些包裝你的頭,而不是使用一些更復雜的內置函數。

0

試着用這個,它會刪除文本文件oky中字符串的所有標點符號。 (str.begin(),str.end(),:: ispunct),str.end());

如果有幫助請回復