Java Scanner没有这样的元素异常

时间:2015-09-02 11:54:14

标签: java

编辑:已解决

我遇到让扫描仪正常工作的问题。我已经搜索了很多关于这一点,他们建议放一个hasNextInt(),但这只是跳过nextLine,所以它继续使用选择的默认值,它会阻止输出。如果我取出hasNextInt,它会给出一个No Such Element Exception。问题在于战斗方法。源代码如下。

public static void game()
{
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println();
    StarterSword starterw = new StarterSword();
    weapons[0] = starterw;
    StarterArmour startera = new StarterArmour();
    armour[0] = startera;
    Heal heal = new Heal();
    items[0] = heal;

    System.out.println();
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println("Lets start with an easy monster fight first.\nLater on it will be harder as monsters evolve.");

    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    int[] b = fight(a, starterw, startera, heal);
    a++;
    int coin = b[0];
    coins = coins + coin;
    System.out.println("You now have " + coins + " coins");
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    contGame();
}

public static void contGame(){
    System.out.println("Now a slightly harder boss!");
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    Scanner choose = new Scanner(System.in);
    while(a <= 40)
    {
        Weapon weapon = PVMGame.weapons[0];
        Armour armour = PVMGame.armour[0];
        Items heal = PVMGame.items[0];
        int[] b = fight(a, weapon, armour, heal);
        int coin = b[0];
        coins = coins + coin;
        System.out.println("You now have " + coins + " coins");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if(b[1] == 1)
        {

            System.out.println("You won! You can go to the next level!");
            a++;
        }
        else
        {

            System.out.println("You lost!");

        }
        choose.close();

    }

}

public static int[] fight(int level, Weapon weapon, Armour armour, Items heal){

    int[] a = new int[2];
    int b = 0;
    int c = 0;
    int damage;
    int health ;
    health = level * 30;
    damage = (level * 4) - 1;
    System.out.println("\nThis Monster has " + health + " health and " + damage + " damage.\n1)Attack\n2)Use Heal(You can only have one of each type of item)\n3)QUIT THIS WHOLE PROGRAMME!!");
    boolean isAlive = true;
    boolean isPAlive = true;
    boolean win = false;
    int pHealth = armour.hp;
    int attack = weapon.damage;
    int healing = heal.healHP;
    String weaponT = weapon.name;
    String armourT = armour.name;
    String healT = heal.name;
    int max = pHealth;
    int totalD = 0;
    int choice = 1;
    @SuppressWarnings("resource")
    Scanner userInput = new Scanner(System.in);
    while(isAlive && isPAlive){

        if(userInput.hasNextInt()){
            choice = userInput.nextInt(); //This is where it goes wrong
        }
        if(choice == 1)
        {

            health = health - attack;

            System.out.println("\nYou inflicted " + attack + " damage on the enemy with your" + weaponT + "\nHe now only has " + health + " health left.");
            if(health <= 0){

                b = (level * 40) - 5;
                System.out.println("You defeated the monster! You won " + b + " coins.");
                a[0] = b;
                win = true;
                isAlive = false;
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            pHealth = pHealth - damage;
            System.out.println("\nThe Monster inflicted " + damage + " damage on your" + armourT + "\nYou only have " + pHealth + " health left.");
            totalD = totalD + damage;
            if(pHealth <= 0){

                System.out.println("You failed.");
                    isPAlive = false;
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            System.out.println("\n1)Attack\n2)Use Heal\n3)QUIT THIS WHOLE PROGRAMME!!");

        }
        else if(choice == 2)
        {
            pHealth = pHealth + healing;
            if(pHealth > max){
                healing = totalD;
                pHealth = max;
            }
            if(healing != 0){
                System.out.println("\nYou healed " + healing + " health on yourself with your" + healT + "\nYou have " + pHealth + " health left.");
            }
            else{
                System.out.println("You have no healing potions left!");
            }
            healing = 0;

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            pHealth = pHealth - damage;
            System.out.println("\nThe Monster inflicted " + damage + " damage on your" + armourT + "\nYou only have " + pHealth + " health left.");
            totalD = totalD + damage;
            if(pHealth <= 0){

                System.out.println("You failed.");
                    isPAlive = false;
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            System.out.println("\n1)Attack\n2)Use Heal\n3)QUIT THIS WHOLE PROGRAMME!!");

        }
        else if(choice == 3)
        {
            System.exit(0);
        }
        else
        {
            System.out.println("TYPE EITHER 1, 2, OR 3");
            fight(level,weapon,armour,heal);
        }

    }
    if(win){

        c = 1;

    }
    if(win == false){

        c = 0;

    }
    a[1] = c;
    return a;
}

2 个答案:

答案 0 :(得分:0)

问题在于:

if(userInput.hasNextInt()){
    choice = userInput.nextInt(); //This is where it goes wrong
}

您没有处理其他情况。把它改成这样的东西:

if(userInput.hasNextInt()){
    choice = userInput.nextInt(); //This is where it goes wrong
} else {
    System.out.println("Invalid input");
    userInput.nextLine(); // Ignore till the end of line
    continue; // Continue again
}

答案 1 :(得分:0)

正如我在评论中提到的那样,这是因为您关闭了System.in流,如果System.in流已关闭,那么您无法重新打开它。您可以看到错误的情况是NoSuchElementException。如果您输入其他内容作为输入而不是预期的整数,那么您将获得InputMismatchException

请参阅thisthis相关问题。

因此,当您退出程序时,最好使用全局Scanner并关闭流,这是最好和最简单的解决方案。

您可以从IDE中获取任何警告,并且永远不要关闭您打开的System.in个流。

最后,我引用的第二个链接中演示的另一个想法是为FileInputStream创建一个System.in包装器,并且永远不会调用close。这是一个例子:

Scanner sc = new Scanner(new FilterInputStream(System.in){public void close(){}});

稍后,您可以执行sc.close(),但System.in将保持打开状态,因为sc.close()没有做任何事情。

这对我来说似乎有些过分。我会采用全球Scanner方式。

最后,期待其他类型的价值观是一个明智的选择,所以我会记住@KDM的建议。