【问题标题】:Java, while infinite loop when using scannerJava,使用扫描仪时的无限循环
【发布时间】:2020-01-10 06:13:14
【问题描述】:

我想要求用户输入一个字符串和四个整数值,如果用户输入类型不匹配,我希望程序继续要求用户输入整数值,为什么代码会一直循环并且永远不会等待如果用户插入了错误的类型,用户输入?

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

public class Main {
public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    String sessionName;
    int pomoInterv, breakInterv, terminalBreakInterv;
    System.out.println("Please, Enter the session name: ");
    sessionName = scanner.nextLine();
    while (true) {
        try {
            System.out.println("Please, Enter the Pomodoro interval: ");
            pomoInterv = scanner.nextInt();
            break;
        } catch (InputMismatchException ex) {
            System.out.println(ex.getMessage());
        }

    }
    while (true) {
        try {
            System.out.println("Please, Enter the break interval: ");
            breakInterv = scanner.nextInt();
            break;
        } catch (InputMismatchException ex) {
            System.out.println(ex.getMessage());
        }

    }
    while (true){
        try {
            System.out.println("Please, Enter the terminal break interval ");
            terminalBreakInterv = scanner.nextInt();
            break;
        } catch (InputMismatchException ex) {
            System.out.println(ex.getMessage());
        }
    }
    System.out.println("Done!");
    System.out.println(sessionName);
    System.out.println(pomoInterv);
    System.out.println(breakInterv);
    System.out.println(terminalBreakInterv);

}
}

【问题讨论】:

  • @ScaryWombat 我不认为这是对那个问题的欺骗,尽管他们有相同的答案。某处可能有更好的欺骗目标......
  • 为这类东西使用库。我可以推荐picocli

标签: java loops input while-loop


【解决方案1】:

根据扫描仪 oracle 文档: https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html

当扫描器抛出 InputMismatchException 时,扫描器不会传递导致异常的令牌,以便可以通过其他方法检索或跳过它。

因此,当您输入除整数以外的任何内容时,scanner.nextInt() 不会将其解析为整数并抛出 InputMismatchException 并且扫描仪不会移动到下一个标记并尝试一次又一次地读取相同的标记。

要解决这个问题,您可以更改循环或使用 hasNextInt() 方法或在 catch 块中使用scanner.next() 以便扫描器可以移动到下一个令牌。

【讨论】:

    【解决方案2】:

    在检查用户输入是否正确时,我总是使用 do-while 循环。

    看看以下是否有效:

        Scanner scanner = new Scanner(System.in);
        String sessionName;
        int pomoInterv = -1, breakInterv = -1, terminalBreakInterv = -1;
        System.out.println("Please, Enter the session name: ");
        sessionName = scanner.nextLine();
        boolean isPomoInterv = false;
        do {
            System.out.println("Please, Enter the Pomodoro interval: ");
            String temp = scanner.nextLine();
            try {
                if (Integer.parseInt(temp) > 0) {
                    pomoInterv = Integer.parseInt(temp);
                    isPomoInterv = true;
                }
            } catch (NumberFormatException e) {
                System.out.println("Try again");
            }
    
        } while (!isPomoInterv);
    
        boolean isBreakInterv = false;
        do {
            System.out.println("Please, Enter the break interval: ");
            String temp = scanner.nextLine();
            try {
                if (Integer.parseInt(temp) > 0) {
                    breakInterv = Integer.parseInt(temp);
                    isBreakInterv = true;
                }
            } catch (NumberFormatException e) {
                System.out.println("Try again");
            }
    
        } while (!isBreakInterv);
    
        boolean isTerminalBreakInterv = false;
        do {
            System.out.println("Please, Enter the terminal break interval ");
            String temp = scanner.nextLine();
            try {
                if (Integer.parseInt(temp) > 0) {
                    terminalBreakInterv = Integer.parseInt(temp);
                    isTerminalBreakInterv = true;
                }
            } catch (NumberFormatException e) {
                System.out.println("Try again");
            }
    
        } while (!isTerminalBreakInterv);
    
        System.out.println("Done!");
        System.out.println(sessionName);
        System.out.println(pomoInterv);
        System.out.println(breakInterv);
        System.out.println(terminalBreakInterv);
    

    scary-wombat 对您的问题的评论是正确的。我已经用他的评论对上面的代码进行了编码。

    【讨论】:

      【解决方案3】:

      我确实解决了,我只需要在下面的catch语句中添加一个(scanner.next();),这是因为Scanner类是如何工作的,见下面的代码,

      import java.util.InputMismatchException;
      import java.util.Scanner;
      
      public class Main {
          public static void main(String[] args) {
          Scanner scanner = new Scanner(System.in);
          String sessionName;
          int pomoInterv, breakInterv, terminalBreakInterv;
          System.out.println("Please, Enter the session name: ");
          sessionName = scanner.nextLine();
          while (true) {
              try {
                  System.out.println("Please, Enter the Pomodoro interval: ");
                  pomoInterv = scanner.nextInt();
                  break;
              } catch (InputMismatchException ex) {
                  scanner.next();
                  System.out.println(ex.getMessage());
              }
      
          }
          while (true) {
              try {
                  System.out.println("Please, Enter the break interval: ");
                  breakInterv = scanner.nextInt();
                  break;
              } catch (InputMismatchException ex) {
                  scanner.next();
                  System.out.println(ex.getMessage());
              }
      
          }
          while (true){
              try {
                  System.out.println("Please, Enter the terminal break interval ");
                  terminalBreakInterv = scanner.nextInt();
                  break;
              } catch (InputMismatchException ex) {
                  scanner.next();
                  System.out.println(ex.getMessage());
              }
          }
          System.out.println("Done!");
          System.out.println(sessionName);
          System.out.println(pomoInterv);
          System.out.println(breakInterv);
          System.out.println(terminalBreakInterv);
      
      }
      }
      

      检查这个答案 https://stackoverflow.com/a/47852703/12565862

      【讨论】:

        【解决方案4】:

        因为你在 catch 块中没有 break;。当出现异常时,您打印消息。但是一旦它从catch块中出来,while循环仍然满足它的条件并再次执行。尝试在 catch 块中添加 break;

        【讨论】:

        • 这很可能是因为您的答案是错误的。是的,while 将继续,用户将输入新信息并继续。
        猜你喜欢
        • 2010-12-20
        • 2011-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多