【问题标题】:Reading input using Scanner causes an infinite loop in Java [duplicate]使用 Scanner 读取输入会导致 Java 中的无限循环 [重复]
【发布时间】:2014-12-28 08:48:46
【问题描述】:

在我的程序中,我试图让用户输入一个介于 1-3 之间的 int,然后根据他们输入的内容做一些事情。如果它不是数字或不是选项之一,那么它将允许他们重新输入一个有效的选项。

我遇到的问题是我无法集思广益,如何不让它无限循环,只允许他们在控制台告诉他们输入无效输入后输入一个数字。

int i = 0;
while (i < 1) {
    try {
        int level = scan.nextInt();
        i+=1;
        if (level == 1) {
            System.out.println("You selected level 1!");
            //Start the game
        } else if (level == 2) {
            System.out.println("You selected level 2!");
            //Start the game
        } else if (level == 3) {
            System.out.println("You selected level 3!");
            //Start the game
        } else {
            System.out.println("That's not an option!");
            i-=1;
        }
    } catch(InputMismatchException input) {
        System.out.println("That's not an option!");
        i-=1;
    }
}

【问题讨论】:

  • 不清楚你要达到什么目的
  • 我需要一种方法来检查用户是否输入了 1-3 之间的有效输入,但如果他们没有重新输入有效输入的能力。
  • 看我的答案,我认为它比当前接受的答案更好,因为代码被分解并且循环的退出条件更清晰。使用带中断的while (true) 循环不是一种好的编程风格
  • @Dici 是的,我做到了,我实现了它来代替我所拥有的
  • 好的,我说当接受的答案不是当前答案时。确实,我没有在catch 子句中看到问题,因此我的回答并不完整

标签: java while-loop infinite-loop ioexception


【解决方案1】:

您可以以更简单的方式进行操作。 3 种有效情况非常相似,可以视为一种,游戏只能在循环后开始一次,因为我们知道一旦循环退出,level 就有一个有效值。

boolean valid = false;
int level;
do  {
    try {
        level = scan.nextInt();
        valid = 1 <= level && level <= 3;

        if (valid) {
            System.out.println(String.format("You selected level %d !",level));    
        } else {
            System.out.println("That's not an option!");
        }
    } catch(InputMismatchException input) {
        scan.next();
        System.out.println("That's not an option!");
    }
} while (!valid);

// start the game

【讨论】:

    【解决方案2】:

    当你输入一个无效的输入时,你需要清除它。触发输入异常时添加scan.next(),以便用next()清除:

     catch(InputMismatchException input) {
            System.out.println("That's not an option!");
            scan.next();
            i-=1;
        }
    

    【讨论】:

    • 正是我需要的谢谢
    • 如果他们输入一个不是数字 1-3 的整数,则 else 为
    • @BlueMoon 不,不会。比如输入4不会抛出任何异常(除非你自己抛出)即使是无效输入
    • @BaileyTincher 我明白了。这是有道理的。
    【解决方案3】:

    你最好这样写代码:

    while(true){
        try{
            int level = scan.nextInt();
            if(level==1){
                System.out.println("You selected level 1!");
                break;
            }else if(level==2){
                System.out.println("You selected level 2!");
                break;
            }else if(level==3){
                System.out.println("You selected level 3!");
                break;
            }else{
                System.out.println("That's not an option!");
                continue;
            }
        }catch(InputMismatchException input){
            System.out.println("That's not an option!");
            continue;
        }
    }
    

    continue 将立即恢复顶部循环的执行,break 将立即跳到 while 的右大括号 }。这消除了i 计数器变量的使用,这对代码完全没用。此外,此代码永远不会无限期运行,除非用户无限期输入不正确的值!

    希望这有帮助,祝你好运!

    【讨论】:

      【解决方案4】:

      不是您期望的答案,但是:重构此代码。请记住 java 的基础知识,其中每个功能位都有自己的方法。所以使用读取输入的方法,并返回选择的级别(如果没有,则返回 -1):

      int readInput() {
        // your code here, returning either the level or -1 on bad input
      }
      

      然后为您的读取循环调用它:

      int selected;
      do {
        selected = readInput();
      } while(selected < 1);
      

      【讨论】:

        猜你喜欢
        • 2016-02-06
        • 1970-01-01
        • 1970-01-01
        • 2021-01-07
        • 1970-01-01
        • 2012-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多