防止用户输入相同的元素(在出现故障的 try catch 中)

Preventing the user from entering identical elements(within a malfunctioning try catch)

因此下面的代码就像一个简单的游戏,其中 objective 用于猜测正确的数字(从 1 到 5)。其他任何不正确的代码都会向用户发出警告消息,如果他们输入类似的 numbers.The 注释将解释声明的循环和变量。

我在这段代码中遇到的唯一问题是我插入了一个 try catch 来处理字符串,但似乎 work.If 没有输入字符串,while 循环无限继续。

此外,我意识到我的代码中存在循环 pf 循环和条件语句,但我想不出任何东西 else.If 您有任何减少循环和 if 语句数量的建议,非常感谢您的帮助。

 public class Tries {
            public static void main(String[]args)
            {


            boolean dataType=false;
            int Inp;
            Scanner a=new Scanner(System.in);
    //The arraylist,List, contains the input that the user enters.Only correct input is entered(1 to 5).
            ArrayList<Integer> List=new ArrayList<Integer>();

    //This determines how many times the for loop is going to execute.Say the user enters 4,and enters 4 correct inputs,the program will exit.The variable num basically determines what the size of the arraylist List is going to be.
                System.out.println("How many tries?");
                int num=a.nextInt();


                boolean datatype=false;

                    for(int j=0;j<num;j++)
                    {
    //This while loop is for the try catch.
                        while(!datatype)
                        {

                        Scanner sc=new Scanner(System.in);

    //This while loop ensures that the user re enters input when anything other than the correct numbers are entered.
                        while(List.size()!=num)
                        {
                            try
                            {
                                System.out.println("\nPick a number: ");
                                Inp=sc.nextInt();

                            if(Inp==1 || Inp==2 || Inp==3 || Inp==4 || Inp==5)
                            {

                                datatype=true;
                                System.out.println(j);

                                if(List.size()==0)
                                {
                                    List.add(Inp);
                                }
                                else if(List.size()>0)
                                {
                                        if(List.contains(Inp))
                                        {
                                            System.out.println("Already entered.Try again.");   
                                        }
                                        else if(!List.contains(Inp))    
                                        {
                                            List.add(Inp);
                                            System.out.println("Added");
                                            dataType=true;

                                            System.out.println(List);
                                        }
                                 }
                            }
                                else
                                {
                                    System.out.println("Option not available.");
                                    datatype=false;
                                }
                             }
                            catch(Exception JavaInputMismatch)
                            {
                                System.out.println("Option not available.Try again.");
                                datatype=false;
                            }
                        }
                    }
                }
            }
        }

因此,当 Inp=sc.nextInt(); 由于用户输入无效数字而失败时,将抛出 InputMismatchException。然后你再次循环,并最终再次尝试 运行 Inp=sc.nextInt();

但问题是输入的无效数字仍在输入流中等待读取。因此在下一个循环中,当再次尝试 Inp=sc.nextInt(); 时,它不会尝试读入新值,它只会读取先前的无效值,不允许您键入任何新值。而且这种情况会无限期地反复发生。

快速修复?在尝试读取新数字之前,您需要清除输入流以去除无效数字。

将修复程序插入程序的最简单方法是在 catch 块中添加一个 sc.next(); 调用,如下所示:

catch(Exception JavaInputMismatch)
{
    sc.next(); // clear the bad token. Without this, it loops infinitely.
    System.out.println("Option not available.Try again.");
    datatype=false;
}

当然还有很多其他 changes/improvements 我会加入该计划,但我承认我目前缺乏解决这些问题的动力。希望这至少会解除你的封锁。

编辑: 我想我可以添加一些可以帮助您的高级建议:

  • 如前所述,您不应有 2 个 Scanner 实例从 System.in 读取。
  • 我建议删除整个 try-catch 以检测无效数字,并在使用 sc.nextInt() 读取数字之前使用 sc.hasNextInt() 进行检查。即使您确实保留了 catch 块,我还是建议您使异常类型尽可能具体(例如 catch(InputMismatchException e)),而不是包罗万象的 Exception。否则,您可能会捕获不相关的异常并以错误的方式处理它们。
  • 您应该能够删除 datatype 布尔变量及其关联的循环。只要列表未满,循环就足够了。
  • 事实上,如果我理解正确,您可以通过只保留执行 while(List.size()!=num) 的那个来简化循环。我认为您可以安全地摆脱执行 for(int j=0;j<num;j++).
  • 的循环
  • 细节较少,但您可以像这样更简洁地表达 if(Inp==1 || Inp==2 || Inp==3 || Inp==4 || Inp==5)if(Inp >= 1 && Inp <= 5).
  • 最后,决定是否将数字添加到列表的逻辑不需要根据列表的大小做一堆条件。

像这样就足够了:

if (List.contains(Inp)) {
    System.out.println("Already entered.Try again.");
} else {
    List.add(Inp);
    System.out.println("Added");
    System.out.println(List);
}

希望对您有所帮助。