std::out_of_range异常排查:C++字符串WUB替换逻辑问题
问题分析与解决:移除字符串中的WUB并替换空格异常问题
问题症状
运行代码时抛出std::out_of_range异常,错误信息显示basic_string::erase: __pos (which is 18446744073709551615),排查后确定问题出在第二个while循环。
核心原因
string::find()方法在找不到目标子串时,会返回string::npos,这个值本质是无符号整数的最大值(也就是错误里的18446744073709551615)。你写的判断条件a.find(b) > 0,当找不到WUB时,npos会被隐式转换成远大于0的正数,导致循环一直执行。此时n = a.find(b)拿到的是npos,用这个值去调用replace,自然会触发越界异常。
另外还有两个隐藏问题:
- 用
cin >> a读取输入会在遇到空格时停止,示例输入里的空格会被截断,导致处理不完整 - 连续多个WUB会被替换成多个连续空格,不符合“单词间只留一个空格”的需求
解决方法
- 修正循环条件:判断
find的结果是否不等于string::npos,而不是大于0 - 改用
getline(cin, a)读取整行输入,避免空格截断 - 替换WUB为空格后,再遍历字符串合并连续空格
- 处理首尾空格(原代码只处理了尾部,建议也处理头部)
修正后的代码
#include <iostream> #include <string> using namespace std; int main() { string a; getline(cin, a); const string b = "WUB"; // 移除开头的WUB while (a.find(b) == 0) { a.erase(0, b.size()); } // 替换中间的WUB为空格,同时处理连续WUB size_t pos; while ((pos = a.find(b)) != string::npos) { // 替换当前WUB为空格 a.replace(pos, b.size(), " "); // 跳过连续的WUB,避免生成多个空格 while (a.find(b, pos) == pos) { a.erase(pos, b.size()); } } // 移除尾部空格 while (!a.empty() && a.back() == ' ') { a.pop_back(); } // 移除头部空格(可选,确保结果更规范) while (!a.empty() && a.front() == ' ') { a.erase(0, 1); } cout << a << endl; return 0; }
代码说明
- 用
size_t类型存储find的结果,避免无符号/有符号类型转换问题 - 替换WUB后,额外处理连续的WUB,直接删除,避免生成多个空格
- 用
getline读取整行,完整获取带空格的输入 - 新增头部空格处理,确保输出的字符串首尾无空格
内容的提问来源于stack exchange,提问作者Aditya Raj
相关产品推荐
相关产品推荐

