2012-05-28 57 views
3

我想從C++中的std :: string中刪除所有的標點符號。我目前的代碼:如何在C++中終止std :: string?

string str_in; 
string::size_type i, j; 

cout << "please input string with punctuation character..." << endl; 
cin >> str_in; 

for (i = 0, j = 0; i != str_in.size(); ++i) 
    if (!ispunct(str_in[i])) 
     str_in[j++] = str_in[i]; 

str_in[j] = '\0'; 

cout << str_in << endl; 

str_in[j] = '\0';錯?

+0

我同意'str_in [J] =「\ 0''是錯誤的,因爲這是不恰當的方式終止一個'std :: string'。什麼是問題? – jamesdlin

+0

如何在C++中終止一個std :: string – iverson

+0

如果你想改變這個問題,這將會很有幫助。與C風格的字符串不同,'std :: string'沒有被定義爲使用終結符。我想你試圖從'std :: string'中刪除所有標點符號,所以''foo.bar + baz''變成'「foobarbaz」'。如果是這樣,那與終止無關。 –

回答

4

如果要將str_in截斷爲第一個j個字符,可以說str_in.resize(j)

如果你想使用標準庫,你可以應用erase-remove成語是這樣的:

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

int main() 
{ 
    std::string str_in; 
    std::getline(std::cin, str_in); 

    // Here is where the magic happens... 
    str_in.erase(std::remove_if(str_in.begin(), str_in.end(), ::ispunct), str_in.end()); 

    std::cout << str_in << '\n'; 

    return 0; 
} 
+0

擦除/ remove_if成語當然是在C++中解決這個問題的唯一合理方法。但是將':: ispunct'作爲謂詞導致未定義的行爲,因爲您無法使用'char'安全地調用':: ispunct'。 (':: ispunct'的輸入必須在'[0,UCHAR_MAX]'或'EOF'範圍內。) –

0

我認爲str_in[j] = '\0'在字符串沒有任何標點符號時是錯誤的。

+0

不管怎樣,這不是一個合適的方式來終止'std :: string'。例如,'str_in.size()'會返回錯誤的值。 – jamesdlin

+0

此方法在C中很有用,但它在C++中不起作用! – iverson

+0

@ jamesdlin哦,是的。它是std :: string,而不是char []。我忘了。 – RolandXu

0

而不是修改相同的字符串的,創建一個新的字符串(例如str_out)和附加到:

str_out += str_in[i]; 
+0

我知道這個方法,我只是想用**相同的**字符串來實現這個功能。 – iverson

+0

@iverson完成後複製到'str_in',或者使用['substr'](http://en.cppreference.com/w/cpp/string/basic_string/substr):'str_in = str_in.substr(0 ,j);' –

+2

或者只是說'str_in.resize(j)' – Blastfurnace

1

的C++字符串類型未實現被空終止(雖然c_str()呼叫給你一個空結束的字符串)

所以,是的,str_in[j] = '\0'是錯誤的,至少有兩個原因:

  1. str_in.length()不會反映您在刪除標點符號時所預期的字符串大小。
  2. 空charatcter是加班包機將被髮送到任何輸出流,
    cout << str_in;

使用您的std::string類可能不應該oveeride相同的緩衝,但可能使用str_out緩衝區,而不是其在複製所有想要的(即不包括標點字符)之後將具有正確的長度,或者您應該調整str_in的長度而不是添加空值。