简体   繁体   English

Java中while循环内try-catch的问题

[英]Problems with try-catch inside while loop in Java

I'm new here and I'm learning Java. 我是新来的,正在学习Java。 In one of my programs, I have made a guessing game. 在我的一个程序中,我做了一个猜谜游戏。 The guessing game is supposed to keep asking the user to input a guess until they guess the number right. 猜谜游戏应该一直要求用户输入一个猜谜,直到他们猜对数字为止。

This is my code: 这是我的代码:

import java.util.InputMismatchException;
import java.util.Random;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        final int minValue = 1;
        final int maxValue = 10;
        final boolean displayHints = true;  // Display whether the number is too high or too low when guessed incorrectly?
        int tries = 1;
        int guess = 0;      // We need to give 'guess' a (temporary) value or else the 'while' loop will create an error
        boolean error = false;

        Random generator = new Random();                        // Create scanner 'generator'
        int random = generator.nextInt(maxValue) + minValue;    // Define 'random' variable with a random value
        if (random == guess) {  // In case 'random' = 'guess'
            guess = -852654;
        }
        Scanner input = new Scanner(System.in); // Create a scanner
        System.out.println("Random number: " + random); // Hey, no cheating! (for debugging purposes)

        System.out.println("Try to guess the magic number! (from " + minValue + " to " + maxValue + ")");
        while (random != guess) {
            do {    // Supposed to ask the user to input a number until they enter a valid number. This is the part of the code that is not working.
                System.out.println("\nInput your guess now!");
                try {
                    guess = input.nextInt();
                    error = false;
                } catch (InputMismatchException e) {
                    System.err.println("That's not a number!\n");
                    error = true;
                    continue;
                }
            } while (error);

            if (guess == random) {
                System.out.println("Correct!");
                System.out.println("Number of tries: " + tries + ".");
                input.close();
            } else {
                tries++;
                if (displayHints) {
                    if (guess < random) {
                        System.out.println("Sorry, too low!");
                    } else if (guess > random) {    // not strictly necessary
                        System.out.println("Sorry, too high!");
                    }
                } else {
                    System.out.println("Sorry, that was not the right number");
                }
            }
        }
    }
}

The code is pretty self-explanatory, because I made a lot of comments. 该代码是不言自明的,因为我做了很多评论。 The problem, though, is when the user enters an invalid integer (like 'banana'), instead of saying "That's not a number!" 但是,问题在于,当用户输入无效的整数(例如“香蕉”)时,而不是说“那不是数字!” and asking for another number, the code does something like this: 并询问另一个数字,代码将执行以下操作:

Random number: 9
Try to guess the magic number! (from 1 to 10)

Input your guess now!
banana

Input your guess now!

Input your guess now!

Input your guess now!

Input your guess now!

Input your guess now!

Input your guess now!

Input your guess now!

Input your guess now!

Input your guess now!

Input your guess now!
That's not a number!

Input your guess now!

That's not a number!

That's not a number!

That's not a number!

That's not a number!

That's not a number!

That's not a number!

That's not a number!

That's not a number!

That's not a number!

That's not a number!

That's not a number!


Input your guess now!
That's not a number!


Input your guess now!
That's not a number!


Input your guess now!
That's not a number!


Input your guess now!
That's not a number!


Input your guess now!
That's not a number!


Input your guess now!
That's not a number!

The rest of the code works perfectly. 其余代码工作完美。

You forgot to consume the bad input. 您忘了消耗不好的输入。 Try consuming the line with the bad input in the catch block. 尝试使用catch块中输入错误的行。

} catch (InputMismatchException e) {
    System.err.println("That's not a number!\n");
    error = true;
    String notANumber = input.nextLine();  // add
    continue;
}

Also, println already adds a newline character at the end of whatever is printing, so there is no need to add additional \\n characters to the strings you're printing. 另外, println已经在打印的末尾添加了换行符,因此无需在要打印的字符串中添加其他\\n字符。

With the above change, here's sample input/output of the do-while loop: 通过上述更改,以下是do-while循环的示例输入/输出:

Input your guess now!
banana
That's not a number!


Input your guess now!
8

As explained by rgettman you need to consume the erroneous input, since if InputMismatchException is risen, the token is not consumed. 正如rgettman解释的那样,您需要使用错误的输入,因为如果InputMismatchException了,则令牌不会被使用。

An alternative solution, to save you from the try/catch block would be to use hasNextInt() : hasNextInt()您免于try/catch块的另一种解决方案是使用hasNextInt()

if (input.hasNextInt())
{
  int guess = input.readInt();
}
else
{
  if (input.hasNextLine())
    input.nextLine();
}

The scanner never actually gets a valid input, so it is repeatedly grabbing banana over and over when you reach guess = input.nextInt(); 扫描程序实际上从未获得有效的输入,因此当您到达guess = input.nextInt();时,它会一遍又一遍地反复抓香蕉guess = input.nextInt();

My fix would be to instead read in the input as a string and parse it to an integer. 我的解决方法是改为以字符串形式读取输入并将其解析为整数。 You would then just need to catch a NumberFormatException instead of a InputMismatchException 然后,您只需要捕获NumberFormatException而不是InputMismatchException

This is how I would do it: 这就是我要做的:

try {
    guess = Integer.parseInt(input.next());
    error = false;
} catch (NumberFormatException e) {
    System.err.println("That's not a number!\n");
    error = true;
}

As many have mentioned, you need to consume the erroneous input. 正如许多人提到的那样,您需要消耗错误的输入。 I was having a very similar problem, and I didn't see an appropriate response here, but I found one elsewhere. 我遇到了一个非常相似的问题,在这里没有看到适当的答复,但是我在其他地方找到了。

Try putting the following line at the end of your catch block. 尝试将以下行放在catch块的末尾。

input.nextLine();

This will clear the buffer and should fix your problem. 这将清除缓冲区并应解决您的问题。

The easiest way is just to change 最简单的方法就是改变

guess = input.nextInt();

to

guess = Integer.valueOf(input.next());

That will solve the problem, only with changing one small line of code. 仅需更改一小段代码,即可解决该问题。 Copy and try it! 复制并尝试!

But I still think your code looks messy. 但是我仍然认为您的代码看起来很凌乱。 I would do something like this 我会做这样的事情

  public static void main(String[] args) {



    Scanner input = new Scanner(System.in);
    Random r = new Random ();
    int x = r.nextInt(10);
    int y = 0;
    int counter=0;


    do{
    System.out.println("Guess a number between 0-10: ");

    try{
    y = Integer.valueOf(input.next());
    }catch (Exception e){
        System.out.println("That is not a number ");
        continue;
    }
    counter ++;

    if (counter>5){
    System.out.println("So you still don't know how to guess quicker?");
    }

    if (y<x){
    System.out.println("You gessed wrong, the number is higher");
    }

    else if (y>x){
    System.out.println("You gessed wrong, the number is lower");
    }

    else if (y==x)
        System.out.println("You gessed right, the number is: " + x);

        }while(y!=x);

    System.out.println("You guessed the number in: " + counter + " times");
    if(counter <=4){
 System.out.println("You found out how to guess the number quickly");
    }
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM