Java 中的数据验证和扫描仪

Data Validation and Scanners in Java

我有一个关于数据验证的问题,scanners.The 下面的一段代码检查 userinput.Anything 不允许使用非整数,用户被要求重新输入 value.My问题是,只有在 loop.The 中声明了扫描器时,代码才有效 如果声明了 outside.Why 程序,程序将无限执行,是吗?谢谢。

int UserInp;
    boolean dataType=false;
    while(dataType==false)
    {
        Scanner sc=new Scanner(System.in);
        try
        {

    System.out.print("\nEnter a number: ");
    UserInp=sc.nextInt();

    dataType=true;
        }
        catch(Exception JavaInputMismatch)
        {

            System.out.println("Option not available.Try again.");

        }

    }

有趣的问题!

发生的情况是扫描器试图将非整数转换为整数,但意识到它不能——因此它抛出一个 InputMismatchException。但是,如果翻译成功,它只会超过令牌。

意思是,无效字符串仍在输入缓冲区中,每次循环并尝试调用 nextInt() 时都会导致翻译失败。您永远不会将 dataType 设置为 true,因此您会无限循环。

要查看实际效果,您可以抓取 catch 块中的任意内容并将其打印出来:

catch(Exception JavaInputMismatch){
    System.out.println( sc.next() );
    System.out.println("Option not available.Try again.");
}

的确,输入无效后,我们得到以下信息:

Enter a number: hello
hello
Option not available.Try again.

Enter a number:

而且我们不会无限循环。这是因为对 next() 的调用从输入缓冲区中获取了值,并将扫描器的指针推进到该缓冲区中的下一个插槽,该插槽现在是空的。所以 nextInt() 在这种情况下将等待输入。

哦,如果你在循环中初始化它工作正常的原因是扫描器将总是开始读取新鲜的输入;扫描器不跨实例共享状态,因此由于重新初始化,上一次迭代缓冲区中的 "hello" 不在下一次迭代的缓冲区中。

技术上,它仍在标准输入缓冲区中,但扫描器指向该缓冲区的指针超出了无效字符串,因为它将开始读取任何 new 输入,不存在输入。

添加到 Purag's answer, you could alternatively use nextLine() 以使扫描器前进到当前行之后。

因此您的 catch 块将如下所示:

catch(Exception JavaInputMismatch)
    {
        System.out.println("Option not available.Try again.");
        sc.nextLine();
    }

棘手的问题。

你可能会得到它!

答案很简单。 Scanner objectwhile loop 之外声明时一直保持到执行结束。在内存级别看这个问题。

Scanner 对象保持活动状态,因此在下次进入循环时,值(字符串值)仍将存在于 Scanner 对象中,并且它不会侦听键盘,因为异常已经 thrown.So 循环继续。

注意:Scanner class 中的 next() 方法将接受所有类型的键盘输入,但不接受 nextInt(), nextFloat() 等其他方法。 ,