尝试/捕获无限循环?

时间:2014-01-01 14:08:29

标签: java while-loop try-catch

帮助,我是java的新手,我正在尝试创建一个循环,要求用户输入一个数字。如果用户输入的数字不是我希望捕获异常的数字,请再次尝试获取正确的输入。我用while循环执行了这个操作,但是在用户输入错误之后它没有给出机会,它会循环除了其他所有内容。请帮我看看有什么不对,以及正确的方法......谢谢。这就是我所拥有的:

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

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

      while ( true ) {
        double numOne;
        System.out.println("Enter an Expression ");
        try {
          numOne = keyboard.nextInt();
          break;
        } catch (Exception E) {
          System.out.println("Please input a number only!");
        } //end catch
      } //end while
    } //end main

3 个答案:

答案 0 :(得分:7)

while ( true ) 
{
  double numOne;
  System.out.println("Enter an Expression ");
  try {
    numOne = keyboard.nextInt();
    break;
  }
  catch (Exception E) {
    System.out.println("Please input a number only!");
  }

这有几个问题:

  • numOne尚未提前初始化,因此try-catch之后不会明确分配,因此您将无法参考它;
  • 如果您计划在循环之后使用numOne ,那么您必须将声明在循环范围内;
  • (您的直接问题)在异常之后您没有调用scanner.next()因此您永远不会使用未解析为int的无效令牌。这会使您的代码在第一次遇到无效输入时进入无限循环。

答案 1 :(得分:5)

使用keyboard.next();子句中的keyboard.nextLine()catch来使用nextInt中遗留的无效令牌。

当抛出InputMismatchException时,扫描程序不会移动到下一个令牌。相反,它为我们提供了使用不同的,更合适的方法处理该令牌的机会,例如:nextLong()nextDouble()nextBoolean()
但是如果你想转移到其他令牌,你需要让扫描仪毫无问题地阅读它。为此,请使用可接受任何数据的方法,例如next()nextLine()。如果没有它,将无法使用无效令牌,并且在另一次迭代nextInt()将再次尝试处理相同的数据再次抛出InputMismatchException,从而导致无限循环。

有关代码中其他问题的详细信息,请参阅@MarkoTopolnik答案。

答案 2 :(得分:0)

在这种情况下,您可能希望使用do ... while循环,因为您总是希望至少在循环中执行一次代码。

int numOne;
boolean inputInvalid = true;
do {
    System.out.println("Enter an expression.");
    try {
        numOne = keyboard.nextInt();
        inputInvalid = false;
    } catch (InputMismatchException ime) {
        System.out.println("Please input a number only!");
        keyboard.next(); // consume invalid token
    }
} while(inputInvalid);
System.out.println("Number entered is " + numOne);

如果抛出异常,则inputInvalid的值保持为真,并且循环保持不变。如果没有抛出异常,则inputInvalid变为false,并允许执行离开循环。

(根据此处其他答案提供的建议,添加了对Scanner next()方法的调用以使用无效令牌。)