程序运行后线程“main”中的异常

时间:2014-09-06 23:42:01

标签: java string exception indexoutofrangeexception

我的程序是确定某种动物(狗/鸡/鱼)有多少腿的游戏。

每次运行程序时,都会收到错误消息:

"Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(Unknown Source)
at AnimalGame.main(AnimalGame.java:67)".

我无法找到问题所在。此外,我希望程序结束后说“你赢了!”#34;或者"你输了!",但每当它说出其中一个输出时,就会说

  

"我不知道那只动物。你想再试一次吗? (Y / N)"

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);

    char n = 0;
    char y = 0;
    char gameAnswer = 'n';

    do
    {
    System.out.println("Choose an animal: ");
    String text = input.nextLine();

        switch (text) {
        case "dog":
            System.out.println("How many legs does a dog have?");
            int dg = input.nextInt();

            if(dg == 4)
            {
                System.out.println("You win!");
            }
            else
            {
                System.out.println("You lose!");
            }
            break;

        case "chicken":
            System.out.println("How many legs does a chicken have?");
            int chkn = input.nextInt();

            if(chkn == 2)
            {
                System.out.println("You win!");
            }
            else
            {
                System.out.println("You lose!");
            }
            break;

        case "fish":
            System.out.println("How many legs does a fish have?");
            int fsh = input.nextInt();

            if(fsh == 0)
            {
                System.out.println("You win!");
            }
            else
            {
                System.out.println("You lose!");
            }
            break;

            default:
                break;
    }
    System.out.println("I don't know that animal. Do you want to try again? (y/n)");
    gameAnswer = input.nextLine().charAt (0);
    }while(gameAnswer == 'y');
}

1 个答案:

答案 0 :(得分:2)

存在一些问题,主要是当用户输入他按下的腿数时#34;输入"它在int之后添加了一个换行符,但由于只读取了int,因此新行被缓冲并在下次读取时使用,这会弄乱所有内容。

解决方法是在readLine()之前的每个case末尾添加break

另一个问题是该行:

System.out.println("I don't know that animal. Do you want to try again? (y/n)");
无论动物是否已知,

总是被打印出来。为此 - 添加known布尔参数修复了问题:

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    char gameAnswer = 'y';

    do {
        System.out.println("Choose an animal: ");
        String text = input.nextLine();

        boolean known = false;
        switch (text) {
            case "dog":
                System.out.println("How many legs does a dog have?");
                int dg = input.nextInt();

                if (dg == 4) {
                    System.out.println("You win!");
                } else {
                    System.out.println("You lose!");
                }
                known = true;
                input.nextLine();
                break;

            case "chicken":
                System.out.println("How many legs does a chicken have?");
                int chkn = input.nextInt();

                if (chkn == 2) {
                    System.out.println("You win!");
                } else {
                    System.out.println("You lose!");
                }
                known = true;
                input.nextLine();
                break;

            case "fish":
                System.out.println("How many legs does a fish have?");
                int fsh = input.nextInt();

                if (fsh == 0) {
                    System.out.println("You win!");
                } else {
                    System.out.println("You lose!");
                }
                known = true;
                input.nextLine();
                break;

            default:
                break;    
        }
        if (!known) {
            System.out.println("I don't know that animal. Do you want to try again? (y/n)");
            String tmp = input.nextLine().trim();
            if (!tmp.isEmpty()) {
                gameAnswer = tmp.charAt(0);
            }
        }    
    } while (gameAnswer == 'y');    
}

既然我们已经有了代码,那么进行一些重构可能是个好主意。我采取了几个步骤,可能会进一步改进:

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    char gameAnswer = 'y';

    do {
        System.out.println("Choose an animal: ");
        String text = input.nextLine();
        boolean known = getLegs(input, text);
        if (!known) {
            System.out.println("I don't know that animal. Do you want to try again? (y/n)");
            String tmp = input.nextLine().trim();
            if (!tmp.isEmpty()) {
                gameAnswer = tmp.charAt(0);
            }
        }
    } while (gameAnswer == 'y');

}

private static boolean getLegs(Scanner input, String animal) {
    boolean known = identifyAnimal(animal);
    if (known) {
        System.out.printf("How many legs does a %s have?\n", animal);
        int legs = input.nextInt();
        if (checkDog(animal, legs) || checkChicken(animal, legs) || checkFish(animal, legs)) {
            System.out.println("You win!");
        } else {
            System.out.println("You lose!");
        }
        /*
        known = true;
        input.nextLine();
        */ 
        return; // since the OP stated in the comments that he wants the code to exit here.
    }
    return known;
}

private static boolean identifyAnimal(String animal) {
    return "dog".equals(animal) || "chicken".equals(animal) || "fish".equals(animal);
}

private static boolean checkDog(String animal, int legs) {
    return legs == 4 && "dog".equals(animal);
}

private static boolean checkChicken(String animal, int legs) {
    return legs == 2 && "chicken".equals(animal);
}

private static boolean checkFish(String animal, int legs) {
    return legs == 0 && "fish".equals(animal);
}