You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++字符串删除子串函数抛出std::out_of_range异常问题求助

问题分析与修复

错误原因

你的代码核心问题在于初始字符串长度slen未同步更新:

  • 你一开始把slen设为字符串的初始长度,但后续调用s.erase()修改字符串后,slen始终保持初始值,完全脱离了字符串的实际长度。
  • 以测试用例s="eemckxmckx"、part="emckx"为例:
    1. 初始slen=10,lenPart=5,循环条件允许i最大到10-5=5。
    2. 第一次在i=1位置匹配到子串,删除后s变为"emckx"(长度5),但slen仍为10,i被设为max(0,1-5)=0。
    3. 再次进入循环,0 <= 10-5成立,调用s.substr(0,5)匹配成功,删除后s变为空字符串(长度0),i仍为0。
    4. 循环条件0 <=5依然成立,此时调用s.substr(0,5),由于s长度为0远小于5,触发std::out_of_range异常。

修复方案

有两种可行的修复方式,核心都是让循环条件基于字符串的实时长度判断:

方式1:直接使用实时长度判断循环条件

string removeOccurrences(string &s, const string &part) {
    int lenPart = part.length();
    int i = 0;
    // 强制转换为int,避免size_t无符号数的溢出问题
    while (i <= (int)s.length() - lenPart) {
        if (s.substr(i, lenPart) == part) {
            s.erase(i, lenPart); 
            i = max(0, i - lenPart);
        } else {
            i++; 
        }
    }
    return s;
}

方式2:删除后同步更新slen

string removeOccurrences(string &s, const string &part) {
    int lenPart = part.length();
    int slen = s.length();
    int i = 0;
    while (i <= slen - lenPart) {
        if (s.substr(i, lenPart) == part) {
            s.erase(i, lenPart); 
            slen = s.length(); // 同步更新为当前字符串长度
            i = max(0, i - lenPart);
        } else {
            i++; 
        }
    }
    return s;
}

补充说明

  • 注意(int)s.length()的转换:string::length()返回的是无符号类型size_t,如果直接计算s.length() - lenPart,当字符串长度小于lenPart时会得到一个极大的无符号数,导致循环错误执行,所以强制转换为int规避该问题。
  • i = max(0, i - lenPart)的逻辑是合理的,用于处理删除子串后,前面的字符可能形成新匹配的场景(比如s="aaaaa"、part="aa",删除后需要回退检查)。

内容的提问来源于stack exchange,提问作者user20273569

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 12:12:33