C++字符串下标访问错误修复:进制转换计数程序异常排查
问题排查与修复:十进制转指定进制并统计最大数字出现次数
问题描述
我正在开发一个程序,功能是将十进制数转换为指定进制,并统计该进制中最大数字(1-8)的出现次数。但程序运行后无法得到正确结果,在VSCode中查看代码中的l[j]时,弹出了std::string::operator[]的下标访问提示,提示越界查找行为未定义。
原代码
string conv(int decimal, int base); vector<int>base10nums; vector<string>differentbase; int main(){ int num,base,start; cin>>num>>base>>start; for(int i=0;i<num;++i){ base10nums.push_back(start+i); } for(int i=0;i<num;++i){ string x=conv(base10nums[i],base); differentbase.push_back(x); } int u=0; int largestdigit=base-1; for(int i=0;i<num;++i){ string l=differentbase[i]; //error here for(int j=0;j<differentbase[i].length();++i){ if(largestdigit==8){ if(l[j]=='8'){ //error here u++; } } if(largestdigit==7){ if(l[j]=='7'){ u++; } } if(largestdigit==6){ if(l[j]=='6'){ u++; } } if(largestdigit==5){ if(l[j]=='5'){ u++; } } if(largestdigit==4){ if(l[j]=='4'){ u++; } } if(largestdigit==3){ if(l[j]=='3'){ u++; } } if(largestdigit==2){ if(l[j]=='2'){ u++; } } if(largestdigit==1){ if(l[j]=='1'){ u++; } } } } std::cout<<u; } std::string conv(int decimal, int base){ if(decimal == 0) return "0"; char NUMS[] = "0123456789ABCDEF"; std::string result = ""; do{ result.push_back(NUMS[decimal%base]); decimal /= base; }while(decimal != 0); return std::string(result.rbegin(), result.rend()); }
报错提示(翻译后)
"inline char &std::string::operator[](std::size_t __pos)
+1 重载对字符串包含的数据进行下标访问。
参数:
__pos – 要访问的字符的索引。返回值:
字符的可读可写引用。该运算符允许以数组式的便捷方式访问数据。注意,使用该运算符的访问是未检查的,越界查找行为未定义(如需检查式查找,请使用at())。"
问题分析
- 内层循环迭代变量错误:内层循环终止条件是
j < differentbase[i].length(),但循环体里写的是++i而非++j,导致j持续增大超出字符串长度,触发越界访问。 - 冗余条件判断:针对每个可能的最大数字写独立if分支完全冗余,可通过数字转字符的方式直接匹配,大幅简化代码。
- 全局变量滥用:
base10nums和differentbase作为全局变量无必要,改为局部变量更符合代码封装原则。 - 函数声明不匹配:
conv函数返回std::string,但声明时未加std命名空间,可能引发编译警告。
修复后的代码
#include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; std::string conv(int decimal, int base); int main(){ int num, base, start; cin >> num >> base >> start; vector<int> base10nums; vector<string> differentbase; for(int i=0; i<num; ++i){ base10nums.push_back(start + i); } for(int i=0; i<num; ++i){ string x = conv(base10nums[i], base); differentbase.push_back(x); } int count = 0; int largestdigit = base - 1; char target_char = '0' + largestdigit; // 直接转换为对应字符 for(int i=0; i<num; ++i){ string current_str = differentbase[i]; for(int j=0; j<current_str.length(); ++j){ // 修正迭代变量为j if(current_str[j] == target_char){ count++; } } } std::cout << count; } std::string conv(int decimal, int base){ if(decimal == 0) return "0"; char NUMS[] = "0123456789ABCDEF"; std::string result = ""; do{ result.push_back(NUMS[decimal % base]); decimal /= base; }while(decimal != 0); return std::string(result.rbegin(), result.rend()); }
关键修改说明
- 修正循环迭代变量:将内层循环的
++i改为++j,确保j在字符串索引范围内循环,避免越界。 - 简化匹配逻辑:通过
'0' + largestdigit将目标数字转换为对应字符,用单个条件判断替代多个冗余分支。 - 调整变量作用域:把
base10nums和differentbase移至main函数内,减少全局变量带来的潜在问题。 - 补全必要头文件:添加
#include <iostream>、<vector>等头文件,确保代码可正常编译。
内容的提问来源于stack exchange,提问作者PeterGriffin
相关产品推荐
相关产品推荐

