C++统计字符串子串出现次数报String subscript out of range错误求调试
问题原因分析
- 最核心的越界错误来源于没有判断下标是否在字符串合法范围内,所有对
s1[n]、s2[m]的访问都没有提前校验n < s1.size()、m < s2.size(),一旦下标超过字符串长度,就会触发String subscript out of range报错。 - 外层循环终止条件错误:仅用
s1[n] != ' '作为循环终止条件,若输入的主字符串末尾没有空格,下标n会持续递增直到超出字符串边界。 - else分支内的跳转逻辑错误:原有内层while循环逻辑完全倒置,在未判断当前下标是否合法的情况下就先执行
n++,同时break条件写反,会直接跳过合法判断触发越界。 - 子串匹配过程中没有校验
m的取值范围,若匹配过程中m超过子串长度,访问s2[m]也会触发越界。
修正后的代码
你原有逻辑是统计主字符串里和目标子串完全匹配的单词数量,修正后代码如下:
#include <iostream> #include <string> using namespace std; int main() { string s1; string s2; int count = 0; int n = 0; cout << "String : "; getline(cin, s1); cout << "Substring : "; getline(cin, s2); int len_s1 = s1.size(); int len_s2 = s2.size(); // 子串为空直接返回 if (len_s2 == 0) { cout << "Substring can not be empty!" << endl; return 0; } while (n < len_s1) { // 跳过开头的空格 while (n < len_s1 && s1[n] == ' ') { n++; } if (n >= len_s1) break; int start = n; // 遍历完当前单词 while (n < len_s1 && s1[n] != ' ') { n++; } int word_len = n - start; // 单词长度和子串一致才比较 if (word_len == len_s2) { bool match = true; for (int i = 0; i < len_s2; i++) { if (s1[start + i] != s2[i]) { match = false; break; } } if (match) count++; } } if (count == 0) { cout << "String contains no substring ! " << endl; } else { cout << "String contains " << count << " substring ! " << endl; } return 0; }
补充说明
如果你需要统计的是任意位置出现的子串次数(不需要匹配整个单词),可以直接调用std::string的find接口实现,逻辑更简洁也不会出现越界问题:
// 任意子串匹配版本核心逻辑 size_t pos = 0; while ((pos = s1.find(s2, pos)) != string::npos) { count++; pos += len_s2; // 允许重叠匹配的话改成pos +=1 }
内容的提问来源于stack exchange,提问作者nghia_pham
相关产品推荐
相关产品推荐

