替换字符串迭代(out_of_range)

ree*_*aal 0 c++ string iterator replace exception

我编写了一个对字符串进行百分比编码的函数,如下所示:

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;
}
Run Code Online (Sandbox Code Playgroud)

当我为"a&b"之类的字符串调用此函数时,会抛出out_of_range异常:

terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::replace
Run Code Online (Sandbox Code Playgroud)

我用调试器跟踪了这个异常,看到替换效果很好,但它以某种方式迭代到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"}
Run Code Online (Sandbox Code Playgroud)

然后它尝试替换"="并失败并出现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();
}
Run Code Online (Sandbox Code Playgroud)

谢谢迭戈:)

Die*_*lla 6

replace 使当前迭代器无效,因此它可能会超出结束范围.

有几种方法可以正确编写此代码.例如,生成(并返回)一个新字符串将更容易,甚至可能更高效(请注意,替换必须将字符串的其余部分移动一个位置).此外,使用索引播放更新的字符串长度和位置.

但是返回一个全新字符串的选项是我能想到的最好的选择.功能更强大:)