我编写了一个对字符串进行百分比编码的函数,如下所示:
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;
}
当我为“a&amp; b”之类的字符串调用此函数时,会抛出out_of_range异常:
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::replace
我用调试器跟踪了这个异常,看到替换效果很好,但它以某种方式迭代超出end();
当我看到迭代器“i”时,这就是我得到的:
{_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();
}
谢谢迭戈:)
答案 0 :(得分:6)
replace
使当前的迭代器无效,因此可能会超出最终目的。
有几种方法可以正确编写此代码。例如,生成(并返回)一个新字符串将更容易,甚至可能更高效(请注意,替换必须将字符串的其余部分移动一个位置)。此外,使用索引播放更新的字符串长度和位置。
但是返回一个全新字符串的选项是我能想到的最好的选择。功能更多:)
答案 1 :(得分:0)
问题是你在迭代时改变了str。更改字符串的内容时,迭代器将失效。解决方案是使用包含转换结果的字符串的另一个副本。