(Java) How to I ensure an exception is thrown if user input is not an integer, and, the user is allowed to give another input?

问题: I am making a very basic battleships game. Unlike the real thing, the program generates three random integers from 0 to 6. The player then has to guess where the ships are...

问题:

I am making a very basic battleships game. Unlike the real thing, the program generates three random integers from 0 to 6. The player then has to guess where the ships are by inputting a integer.

I am a beginner to Java and have just briefly covered throwing exceptions and try / catch.

So, the program as it is now:

public class digitBattleShips {

static int choice;
int playerScore;

int shipLoc1;
int shipLoc2;
int shipLoc3;

Random rand = new Random();
static Scanner input = new Scanner(System.in);

public void digitBattleShipsGame() {

    shipLoc1 = rand.nextInt(7);

    shipLoc2 = rand.nextInt(7);

    shipLoc3 = rand.nextInt(7);

    System.out.println(
            "Welcome to digit BattleShips! In this game, you will choose a 
          number from 0 to 6. There are 3 ships to destroy, if you get them 
      all, you win");

    while (playerScore != 3) {

        System.out.println("Choose a number from 0 to 6");

        playerChoice();

        if (choice == shipLoc1 || choice == shipLoc2 || choice == shipLoc3) {
            System.out.println("KABOOOOOOM!");

            playerScore++;
        } else {
            System.out.println("Sploooosh...");
        }



    }

    System.out.println("HURRRAAAAAAY you win");

}

public static void playerChoice() {

    try {
    choice = (int) input.nextInt();

    while (choice<0 || choice>6) {
        System.out.println("Error. You have to choose a number from 0 to 6");
        playerChoice();
    } }

    catch (InputMismatchException ex) {

        System.out.println("Invalid input! You have to enter a number");

        playerChoice();
    }

}

public static void main(String[] args) {

    digitBattleShips digit = new digitBattleShips();

    digit.digitBattleShipsGame();
}

}

At the moment, this is what happens:

1 ) If the player chooses an integer from 0 to 6 the while loop works as intended and will continue until the player hits the three ships represented by shipLoc1, shipLoc2 and shipLoc3

2 ) If the player chooses a number above or below 0 and 6, an error is shown, and the player gets prompted again for another input. Works as intended here.

3 ) If the player chooses a char, string, float number etc. then the exception is thrown BUT it does not allow the player to have another chance of changing their input.

I thought creating a method specifically designed (named playerChoice() as in the code) to allow input would sort this out and hence, after the exception is thrown, this method activates again so the player can choose another number. However, from my limited understanding, it does look like that the invalid choice is stored and hence, when this method is called, the exception is automatically thrown again as the invalid choice stays throughout. This then creates an infinite loop of the exception being thrown.

The idea is to allow another input if the one before it is invalid i.e. not an integer so that 3) operates in the same manner as 2)

I think the confusion I am facing here may be due to how I placed the while and try / catch techniques. Please provide some direction and how to prevent 3) from happening


回答1:

This is what I would do:

public static void playerChoice()
{
    try
    {
        String inStr = input.nextLine();
        int inInt = Integer.parseInt(inStr); // throws exception.
        if (inInt < 0 || inInt > 6) // If number out of range, try again.
        {
            System.out.println("Error. You have to choose a number from 0 to 6");
            playerChoice();
        }
        else
        {
            choice = inInt;
        }
    }
    catch (NumberFormatException ex) // If exception, try again.
    {
        System.out.println("Invalid input! You have to enter a number");
        playerChoice();
    }
}

Instead of relying on Scanner.nextInt(), I would read the input as String first (since no parsing is involved at this step), then use Integer.parseInt() to parse manually. It is usually a good practice to seperate reading/fetching from casting/parsing.


回答2:

After a little bit of googling it looks like input isn't cleared after the exception is thrown (see How does input.nextInt() work exactly?).

As a result, because you aren't calling "input.next();", it keeps reading the same input, realizing it isn't an integer and throwing the exception.

Solution:

 try {
choice = (int) input.nextInt();

while (choice<0 || choice>6) {
    System.out.println("Error. You have to choose a number from 0 to 6");
    playerChoice();
} }

catch (InputMismatchException ex) {

    System.out.println("Invalid input! You have to enter a number");
    input.next();
    playerChoice();
}
  • 发表于 2018-07-10 01:51
  • 阅读 ( 175 )
  • 分类:sof

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除