如何在代码中摆脱StringIndexOutOfBoundsException?

时间:2017-10-07 21:29:24

标签: java exception stringindexoutofbounds

这是我关于stackoverflow的第一个问题。我想测试自己并制作一种迷你编程语言。但自从我决定扩展我的代码以来,我一直在获取StringIndexOutOfBoundsExceptions。我已经在stackoverflow和youtube上做了一些研究,看起来我有一个特定的问题。你能看一下吗? 先感谢您... PS:很抱歉变量名称令人困惑,我用我的母语命名:P 代码:

import java.util.Scanner;
import java.util.Vector;

public class Komanda {
private String tip;
private String naziv;
private String parametar;
public Komanda() {
    super();
}
public Komanda(String tip, String parametar) {
    super();
    this.tip = tip;
    this.parametar = parametar;
}
public Komanda(String tip, String naziv, String parametar) {
    super();
    this.tip = tip;
    this.naziv = naziv;
    this.parametar = parametar;
}
public String getTip() {
    return tip;
}
public void setTip(String tip) {
    this.tip = tip;
}
public String getNaziv() {
    return naziv;
}
public void setNaziv(String naziv) {
    this.naziv = naziv;
}
public String getParametar() {
    return parametar;
}
public void setParametar(String parametar) {
    this.parametar = parametar;
}
}


public class Main {

public static void execute(Vector<Komanda> code) {
    for (int i = 0; i < code.size(); i++) {
        if (code.elementAt(i).getTip().equals("print:")) {
            if (!code.elementAt(i).getParametar().contains(":")) {
                System.out.println(code.elementAt(i).getParametar());
            } else {
                System.out.println("");
                System.out.print(code.elementAt(i).getParametar().substring(0,
                        code.elementAt(i).getParametar().indexOf(':') + 1));
                for (int k = 0; k < code.size(); i++) {
                    if (code.elementAt(k).getNaziv().equals(code.elementAt(i).getParametar()
                            .substring(code.elementAt(i).getParametar().indexOf(':') + 1))) {
                        System.out.print(" " + code.elementAt(k).getParametar());
                    }
                }
            }
        }
        if (code.elementAt(i).getTip().equals("var")) {

        }
    }
}

public static void main(String[] args){
    Vector<Komanda> code = new Vector<Komanda>();
    Scanner console = new Scanner(System.in);
    System.out.println("NNS 0.1 (v0.1.0:1, Oct  7 2017, 18:40:49) [MSC v.1900 64 bit]");
    for (int i = 0; i < 1;) {

        String line = console.nextLine();
        Scanner lineRreader = new Scanner(line);
        if (lineRreader.next().equalsIgnoreCase("SLC;")) {
            code.removeAllElements();
            line = line.substring(line.indexOf(';') + 2);
            if (line.equals("terminate")) {
                break;
            }
            if (lineRreader.next().equals("print:")) {
                System.out.println(line.substring(line.indexOf(':') + 2));
            }
            if (line.substring(0, line.indexOf(' ')).equals("print")) {
                line = line.substring(line.indexOf(' ') + 1);
                int firstNumber = lineRreader.nextInt();
                char operation = lineRreader.next().charAt(0);
                int secondNumber = lineRreader.nextInt();
                System.out.print(firstNumber + " " + operation + " " + secondNumber);
                switch (operation) {
                case '+':
                    int a = firstNumber + secondNumber;
                    System.out.print(" = " + (int) a);
                    break;
                case '-':
                    int b = firstNumber - secondNumber;
                    System.out.print(" = " + (int) b);
                    break;
                case '*':
                    int c = firstNumber * secondNumber;
                    System.out.print(" = " + (int) c);
                    break;
                case '/':
                    double d = firstNumber / secondNumber;
                    System.out.print(" = " + (double) d);
                    break;
                }
                System.out.println("");
            }

        } else {
            if (line.substring(0, line.indexOf(' ')).equalsIgnoreCase("print: ")) { // THIS IS THE 72ND LINE
                code.add(new Komanda("print:", line.substring(line.indexOf(' ')+1)));
            }
            else if (line.substring(0, line.indexOf(' ')).equalsIgnoreCase("var")) {
                code.add(new Komanda("var", lineRreader.next(),
                        line.substring(line.lastIndexOf(' ') + 1, line.length())));
            }
            else if (line.equalsIgnoreCase("exec")) {
                execute(code);
            }

        }
        lineRreader.close();
    }
    console.close();
}

}

MY CONSOLE OUTPUT:

NNS 0.1 (v0.1.0:1, Oct  7 2017, 18:40:49) [MSC v.1900 64 bit] <--STATUS STRING
print: helloworld <---- ME TYPING PRINT: COMMAND
exec <---- THIS IS THE COMMAND THAT TRIGGERS THE EXCEPTION
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String 
index out of range: -1
    at java.lang.String.substring(Unknown Source)
    at Main.main(Main.java:72)

2 个答案:

答案 0 :(得分:0)

execute方法中,你有内部for循环,如下面的

for (int k = 0; k < code.size(); i++)

此处您正在递增i而不是k。您使用substring致电i。我认为这个问题就在这里。因为for循环永远不会结束,最终会得到iindexOutOfBound

答案 1 :(得分:0)

从你的问题:

getTheme().applyStyle(switchValue? R.style.AppTheme1:R.style.AppTheme2 , true);

你得到了例外,因为你有这样的条件:

exec <---- THIS IS THE COMMAND THAT TRIGGERS THE EXCEPTION

由于if (line.substring(0, line.indexOf(' ')).equalsIgnoreCase("print: ")) { // ... } else if (line.substring(0, line.indexOf(' ')).equalsIgnoreCase("var")) { // ... } else if (line.equalsIgnoreCase("exec")) { // ... } 不包含空格,exec会返回-1,而line.indexOf(' ')会失败,因为第二个参数为负数。您无法到达line.substring(0, -1)的支票,因为它会在检查后抛出异常。

在需要空格的条件之前移动要检查的exec,例如

if (line.equalsIgnoreCase("exec"))

虽然您可能希望将if (line.equalsIgnoreCase("exec")) { // ... } else if (line.substring(0, line.indexOf(' ')).equalsIgnoreCase("print: ")) { // ... } else if (line.substring(0, line.indexOf(' ')).equalsIgnoreCase("var")) { // ... } 的值提取到变量,并明确检查这是否为非负数,因此您可以避免在行不是{{{{{{ 1}}并且不包含空格:

line.indexOf(' ')

请注意,使用exec可以减少错误并提高效率:这样可以避免显式创建子字符串以检查if (line.equalsIgnoreCase("exec")) { // ... } else { int spacePos = line.indexOf(' '); if (spacePos >= 0) { if (line.substring(0, spacePos).equalsIgnoreCase("print: ")) { // ... } else if (line.substring(0, spacePos).equalsIgnoreCase("var")) { // ... } } } 是否以给定字符串开头。该方法本身有点麻烦,但您可以将其包装到方法中:

String.regionMatches

现在您可以保留条件的原始顺序:

line