罗马数字转整数问题:修复首字符为M时的索引越界错误
修复罗马数字转整数中的索引越界问题
你的问题出在处理V和M的分支中,直接调用input.at(i-1)获取前一个字符——当当前字符是字符串的第一个字符(i=0)时,i-1等于-1,超出了字符串的合法索引范围,自然触发越界错误。
修复思路
- 避免越界访问:在尝试获取前一个字符前,必须先判断当前索引
i是否大于0,只有i>0时才去访问前一个字符。 - 完善特殊组合处理:罗马数字的特殊减法组合有6种(IV、IX、XL、XC、CD、CM),你的代码目前只处理了两种,建议统一逻辑覆盖所有情况。
- 优化变量作用域:把全局的
character和integer改成局部变量,更符合C++编程规范,避免全局变量带来的潜在问题。
修改后的完整代码
#include <iostream> #include <string> using namespace std; int main() { // Roman numeral given string input; // The integer value that is needed to add up and output the corresponding value int integer = 0; // Prompt for user to enter the roman numeral integer cout << "Enter the roman numeral you want to convert into a number: " << endl; cin >> input; cout << input << " is what you are wanting to convert." << endl; // Read through the string that is being inputted then assign values to the overall integer for (int i = 0; i < input.length(); i++) { char character = input.at(i); cout << "This is the character that is being read right now: " << character << endl; // Arithmetic for when the character is found and the corresponding value needs to be added if(character == 'I') { integer += 1; cout << "Integer value now: " << integer << endl; } else if(character == 'V') { integer += 5; // 只有不是第一个字符时,才判断前一个字符 if(i > 0 && input.at(i-1) == 'I') { integer -= 2; } cout << "Integer value now: " << integer << endl; } else if(character == 'X') { integer += 10; if(i > 0 && input.at(i-1) == 'I') { integer -= 2; } cout << "Integer value now: " << integer << endl; } else if(character == 'L') { integer += 50; if(i > 0 && input.at(i-1) == 'X') { integer -= 20; } cout << "Integer value now: " << integer << endl; } else if(character == 'C') { integer += 100; if(i > 0 && input.at(i-1) == 'X') { integer -= 20; } cout << "Integer value now: " << integer << endl; } else if(character == 'D') { integer += 500; if(i > 0 && input.at(i-1) == 'C') { integer -= 200; } cout << "Integer value now: " << integer << endl; } else if(character == 'M') { integer += 1000; // 修复越界问题:先判断i>0再访问前一个字符 if(i > 0 && input.at(i-1) == 'C') { integer -= 200; } cout << "Integer value now: " << integer << endl; } } cout << "The integer value is: " << integer << endl; return 0; }
关键改动说明
- 在所有需要访问前一个字符的分支中,都增加了
i > 0的判断,彻底避免了索引越界的情况。 - 补充了所有罗马数字的特殊减法组合处理,现在可以正确转换像
MCMXCIV(对应1994)这类包含多种特殊组合的罗马数字。 - 将全局变量移到
main函数内,缩小了变量作用域,代码更健壮。
内容的提问来源于stack exchange,提问作者Shahim Panjwani
相关产品推荐
相关产品推荐

