更换

2011-05-19 12 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而迭代它。当您更改字符串的内容时,迭代器会失效。解决方法是使用将包含转换结果的字符串的另一个副本。