更換

2011-05-19 13 views
0

我寫了一個函數,其百分比-字符串編碼,如下所示:更換

string percent_encode(string str) 
{ 
    string reserved = 
    // gen-delims 
    ":/?#[]@" 
    // sub-delims 
    "!$&'()*+,;=" 
    ; 

    for(string::iterator i = str.begin(); i < str.end(); i++) { 
    int c = *i; 
    // replaces reserved, unreserved non-ascii and space characters. 
    if(c > 127 || c == 32 || reserved.find(*i) != string::npos) { 
     std::stringstream ss; 
     ss << std::hex << c; 
     str.replace(i, i + 1, "%" + ss.str()); 
    } 
    } 
    return str; 
} 

當我調用該函數對於喜歡「一個& b」的一個字符串,一個out_of_range例外是拋出:

terminate called after throwing an instance of 'std::out_of_range' 
    what(): basic_string::replace 

我用一個調試器跟蹤這個異常,看到替換工作得很好,但它迭代超出end();

這是我得到的,當我看迭代「我」:

{_M_current = 0x7fc43d61bd78 "a&b"} 
{_M_current = 0x7fc43d61bd79 "&b"} 
{_M_current = 0x7fc43d61bd7a "b"} 
{_M_current = 0x7fc43d61bd7b ""} 
{_M_current = 0x7fc43d61bd7c "o = a&b\n"} 
{_M_current = 0x7fc43d61bd7d " = a&b\n"} 

,然後嘗試更換「=」和失敗的out_of_range例外。 我不明白,迭代器如何明顯超越end()。

如果有人能解釋我,這是如何可能的,因爲我找不到網絡中有人遇到同樣的問題,我將不勝感激。

感謝和問候,

reeaal

編輯:

哎呀,我真的以爲複雜的。 x) 這就是我現在解決它的方法。

string percent_encode(string str) 
{ 
    string reserved = 
    // gen-delims 
    ":/?#[]@" 
    // sub-delims 
    "!$&'()*+,;=" 
    ; 

    std::stringstream ss; 

    for(string::iterator i = str.begin(); i < str.end(); i++) { 
    // encodes reserved, unreserved non-ascii and space characters. 
    int c = *i; 
    if(c > 126 || c == 32 || reserved.find(*i) != string::npos) { 
     ss << '%' << std::hex << c; 
    } else { 
     ss << *i; 
    } 
    } 

    return ss.str(); 
} 

感謝迭戈:)

回答

6

replace無效當前迭代器,因此它可能超越結束。

有幾種寫這段代碼的方法是正確的。例如,生成(並返回)一個新的字符串會更容易,甚至更有效(注意,替換必須將字符串的其餘部分移動一個位置)。此外,玩更新的字符串長度和位置與索引。

但是返回一個全新字符串的選項是我能想到的最好的選擇。更多的功能:)

+0

恩......好主意,沒想過,謝謝。 :) – reeaal 2011-05-19 22:30:49

+0

好的,你的解決方案的作品。它有一點點的開銷,因爲stringstream,但無論如何:) – 2011-05-19 22:44:08

+0

你覺得怎麼樣? :)無論如何,我需要將其轉換爲十六進制表示。 – reeaal 2011-05-19 22:55:21

0

問題是,你改變str而迭代它。當您更改字符串的內容時,迭代器會失效。解決方法是使用將包含轉換結果的字符串的另一個副本。