InputMismatchException 仍然显示

InputMismatchException still showing

我希望 java 给我随机数,用户会尝试猜测它,如果用户尝试输入无效的数据类型,它会说:“输入无效。仅限整数。再试一次”并将继续执行代码,但即使有 while 循环,代码也不会在显示消息后继续执行。

我的全部:

import java.util.*;
public class tine {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Random ranNum = new Random();
boolean Win = false;
int nAttempt = 0;
int number = (int)(Math.random()*50 );

int userInput;
System.out.println("Guess a number from 1-50!");    
while (Win == false) {
nAttempt++;
try {       
    userInput = sc.nextInt();
    if (userInput < number && userInput >= 1) {
        System.out.println("too low.");
}
    else if (userInput > number && userInput <= 50){
        System.out.println("too high"); 
}
    else if (userInput == number) {
        System.out.println("you got it right in " +nAttempt +" attemp(s)"); 
        Win = true;     
}
    else {
        throw new InvalidInputException();
        
    }
}   
    catch (InputMismatchException im) {
        System.out.println("Invalid Input. Integer only. Try Again");
        userInput = sc.nextInt();
        nAttempt--;
    
}
    catch (InvalidInputException iie) {
        System.out.println("Number is out of range. Try Again.");
        userInput = sc.nextInt();
        nAttempt--; 
        }
    }   
}   

}

    class InvalidInputException extends Exception {
        InvalidInputException(){
        super();
}       

}

根据java API specification on Scanner

A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.

nextInt() 会:

Scans the next token of the input as an int.

因此,包含空格的输入将被视为多个输入,可能无法按预期工作。

要解决此问题,我建议使用 Scanner.nextLine() 扫描整行,其中“returns 当前行的其余部分,不包括末尾的任何行分隔符”; 然后使用 Integer.parseInt(String) 将该行解析为整数,这会在非法模式上抛出运行时异常 NumberFormatException,因此不妨将其包含在 catch 语句中:

try
{
    String ln = sc.nextLine();
    userInput = Integer.parseInt(ln);
    
    ...
}
catch (InputMismatchException | NumberFormatException im)
{...}
catch (InvalidInputException iie)
{...}

我也没有看到在 catch 块中读取 userInput 的意义,因为它会在 try 块的第一行再次更新,因为 while 循环的另一个循环开始了。因此我建议删除它们:

catch (InputMismatchException im)
{
    System.out.println("Invalid Input. Integer only. Try Again");
    // userInput = sc.nextInt();
    nAttempt--;                               
}
catch (InvalidInputException iie)
{
    System.out.println("Number is out of range. Try Again.");
    // userInput = sc.nextInt();
    nAttempt--;
}