2011-03-21 88 views
0

我正在嘗試編寫一個程序去除字符串中的標點符號。程序的輸入應該是一串包含標點符號的字符;輸出應該是刪除標點符號的字符串。我正在使用Visual Studio 2008來編譯和運行該程序。執行它時,我收到異常:「調試斷言失敗,表達式:字符串下標超出範圍。」重構一個字符串時刪除標點符號的問題

什麼 我在這裏做錯了嗎?

int main() 
{  
    string input; 
    string output; 

    getline(cin, input); 

    string::size_type i = 0; 
    for (string::size_type ix = 0; ix != input.size(); ++ix) 
    { 

     if (!ispunct(input[ix])) 
     { 
      output[i] = input[ix]; 
      ++i; 
     } 

    } 


    cout << output << endl; 

    return 0; 
} 

回答

4

您沒有爲output變量設置有意義的大小,因此您正在訪問不存在的元素。您需要output.push_back(input[ix]);

+0

+1:因爲我們知道循環之前的大小。我們可以重新調整輸出的大小,而不是依靠實施來重新調整輸出大小(可能需要幾次)。我不能聲稱我更喜歡它,因爲我也在我的解決方案中錯過了它:-) – 2011-03-21 17:17:16

1

使用此:

output += input[ix]; 

output是空的 - output[i]試圖訪問輸出到外部的邊界。 std::string將不會自動調整大小,如果您嘗試訪問越界。

2

您從未爲輸出string分配任何空間。實際上,你告訴它寫入未定義的內存位置,導致斷言。

,如果你想徹底刪除標點或者只是改變它說的空間,我也說不上來,但假設你想刪除它完全使用您的if檢查裏面:

output.push_back(input[ix]);

2

嘗試標準算法:

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

int main() 
{ 
    std::string input; 
    std::string output; 

    std::getline(std::cin, input); 

    // This method copies items from the input container to the output container. 
    // Unless the predicate is true (for the character being tested. 
    // http://www.sgi.com/tech/stl/remove_copy_if.html 
    std::remove_copy_if(input.begin(), input.end(),   // Input container 
         std::back_inserter(output),   // Output (note the back inserter) 
         std::ptr_fun<int, int>(&std::ispunct) // a function that tests for punct. 
         ); 

    std::cout << output << "\n"; 
} 

與原來的代碼(其不分配用於輸出空間),此使用的std :: back_inserter迭代的push_back()新元素插入到輸出容器(噸hus自動生成所需的空間)。

相關問題