我有一个关于数据验证和扫描仪的问题。以下代码检查userinput。不允许除整数以外的任何内容,并要求用户重新输入一个值。我的问题是代码只在扫描仪在while循环中声明。如果扫描仪在外面声明,程序将无限执行。为什么?谢谢。
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.");
}
}
答案 0 :(得分:5)
有趣的问题!
会发生什么情况是扫描程序尝试将非整数转换为整数,并意识到它不能 - 因此它会抛出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 输入,而不是输入
答案 1 :(得分:1)
要添加到Purag的答案,您还可以使用nextLine()
使扫描程序超过当前行。
所以你的catch块看起来像这样:
catch(Exception JavaInputMismatch)
{
System.out.println("Option not available.Try again.");
sc.nextLine();
}
答案 2 :(得分:0)
棘手的问题。
你可能会得到它!
答案很简单。 Scanner object
保持活动直到执行结束,因为它在while loop
之外声明。在内存级别查看此问题。
Scanner对象保持活动状态,因此下次进入循环时,仍然会在Scanner对象中存在值(字符串值),并且由于异常已经被抛出,因此它不会监听键盘。所以循环继续
注意:next()
类中的Scanner
方法将接受所有类型的键盘输入,但不接受其他方法,例如nextInt(), nextFloat()
等。