这是我关于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)
答案 0 :(得分:0)
在execute
方法中,你有内部for循环,如下面的
for (int k = 0; k < code.size(); i++)
此处您正在递增i
而不是k
。您使用substring
致电i
。我认为这个问题就在这里。因为for循环永远不会结束,最终会得到i
值indexOutOfBound
答案 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