字符串索引超出范围错误

时间:2016-07-27 10:24:51

标签: java string indexoutofboundsexception

bellow类在此方法中包含方法fromRomanToArabic ()我正在尝试将阿拉伯数字转换为罗马数字。该方法应如下:

  • 从对象中获取用户字符串
  • 通过字符串
  • 进行迭代
  • 将与字符关联的值相加。如果字符关联数字大于前一个字符,则从总和中扣除字符值。

这是我的代码:

package romantoarabicnums;

import javax.swing.JOptionPane;


public class RomanToArabicNums {
    private static String userString;
    private static int userNumber;
    private static char letter;
    private static int letterNum;

    public RomanToArabicNums (String s) throws NumberFormatException {
        for (int i = 0; i < s.length(); i++) {

           if (s.charAt(i) == 'M' ||s.charAt(i) == 'D' ||s.charAt(i) == 'C' ||s.charAt(i) == 'X' ||
               s.charAt(i) == 'V' ||s.charAt(i) == 'I' ||s.charAt(i) == 'L') {
               userString += s.charAt(i);
           }
           else {throw new NumberFormatException("Only M,C,D,X,V and I allowed");}
        }
    }
    public RomanToArabicNums (int num) throws NullPointerException {
       if (num >= 1 && num <= 3999) {
           RomanToArabicNums.userNumber = num;
       }
       else {throw new NumberFormatException("numbers between 1 and 3999 only!");}
    }
    public RomanToArabicNums (char let, int num) {
        RomanToArabicNums.letter = let;
        RomanToArabicNums.letterNum = num;
    }
    public static void main(String[] args) {
        RomanToArabicNums r2 = new RomanToArabicNums("MCMXCV");
        System.out.println("the arabic number is: " + r2.fromRomanToArabic());

    }
    /* convert Roman characters to Arabic numbers */
    public int fromRomanToArabic () {
            int sum = 0;

            for (int i = 0; i <= userString.length(); i++) {
                /**/
                if (userString.charAt(i) == 'M') {
                    sum += 1000;
                }
                /**/
                if (userString.charAt(i) == 'D') {
                    if (userString.charAt(i + 1) == 'M') {
                        sum -= 500;
                    } else {
                        sum += 500;
                    }
                }
                /**/
                if (userString.charAt(i) == 'C') {
                    if (userString.charAt(i + 1) == 'M' || userString.charAt(i + 1) == 'D') {
                        sum -= 100;
                    } else {
                        sum += 100;
                    }
                }
                /**/
                if (userString.charAt(i) == 'L') {
                    if (userString.charAt(i + 1) == 'M' || userString.charAt(i + 1) == 'D'
                            || userString.charAt(i + 1) == 'C') {
                        sum -= 50;
                    } else {
                        sum += 50;
                    }
                }
                /**/
                if (userString.charAt(i) == 'X') {
                    if (userString.charAt(i + 1) == 'M' || userString.charAt(i + 1) == 'D'
                            || userString.charAt(i + 1) == 'C' || userString.charAt(i + 1) == 'L') {
                        sum -= 10;
                    } else {
                        sum += 10;
                    }
                }
                /**/
                if (userString.charAt(i) == 'V') {
                    if (userString.charAt(i + 1) == 'M' || userString.charAt(i + 1) == 'D'
                            || userString.charAt(i + 1) == 'C' || userString.charAt(i + 1) == 'L'
                            || userString.charAt(i + 1) == 'X') {
                        sum -= 5;
                    } else {
                        sum += 5;
                    }
                }
                /**/
                if (userString.charAt(i) == 'I') {
                    if (userString.charAt(i + 1) == 'M' || userString.charAt(i + 1) == 'D'
                            || userString.charAt(i + 1) == 'C' || userString.charAt(i + 1) == 'L'
                            || userString.charAt(i + 1) == 'X' || userString.charAt(i + 1) == 'V') {
                        sum -= 1;
                    } else {
                        sum += 1;
                    }
                }
            }
            return sum;

    }
}

这是错误: enter image description here

注意:我认为错误是由于字符串元素的数量少于for循环中的步骤

6 个答案:

答案 0 :(得分:2)

所以字符串是零基础,你必须运行你的循环,直到:i < userString.length()

for (int i = 0; i < userString.length(); i++) {

还有更多错误,你可以从字符串的长度中获得一个字符。

答案 1 :(得分:1)

除了Jens'和Andy的答案,你应该检查i + 1 < userString.length(),因为你使用userString.charAt(i + 1) == 'M'

如果您在最后一个字符的索引处,这也会导致IndexOutOfBoundsException

请注意,您需要相应地处理最后一个字符,或者保留i < userString.length()并添加一个检查i + 1是否超过字符串的长度{。{}}。

答案 2 :(得分:0)

参考String.charAt(int)的Javadoc:

  

[throws] IndexOutOfBoundsException - 如果index参数为负数或不小于此字符串的长度。

因此,只要您调用userString.charAt,就需要确保索引满足以下条件:

  • i <= userString.length()应为i < userString.length()。这意味着所有userString.charAt(i)次调用都会成功;
  • userString.charAt(i + 1)的所有来电都需要事先检查i + 1 < userString.length(),例如

    if (i + 1 < userString.length() && userString.charAt(i + 1) == 'M') {
    

    逻辑上,这些调用正在检查“下一个字符”。通过首先检查i + 1的值,此检查基本上是:

    if ((there is a next character) AND (the next character is 'M')) {
    

答案 3 :(得分:0)

我根本没有这个。但是您在方法中执行以下操作:

   for (int i = 0; i <= userString.length(); i++)

你应该这样做:

   for (int i = 0; i < userString.length(); i++)

答案 4 :(得分:0)

您在userString.charAt(i + 1)

的循环中使用i <= userString.length()

因此有2个索引将超出范围 i == n - 1i == n

更改循环定义
for (int i = 0; i <= userString.length(); i++) {

for (int i = 0; i < userString.length() - 1; i++) {

答案 5 :(得分:0)

您的代码中存在两个问题。一个是显而易见的 - 你正在循环for (int i = 0; i <= userString.length(); i++)而不是for (int i = 0; i < userString.length(); i++)。第二个更隐蔽。在致电i + 1 < userString.length()之前,您不会检查是否charAt(i+1)。修正这两个错误将允许您转换有效的罗马数字。

还有一件事。名为RomanToArabic的班级不是将Arabic转换为Roman的最佳位置。考虑将类的名称重构为RomanArabicConverter或将您的逻辑划分为两个单独的类,并提供一个类aggregate两个类。