如何防止扫描仪在input错误types时抛出exception?
以下是一些示例代码:
import java.util.Scanner; class In { public static void main (String[]arg) { Scanner in = new Scanner (System.in) ; System.out.println ("how many are invading?") ; int a = in.nextInt() ; System.out.println (a) ; } }
如果我运行程序,并给它一个像4
这样的int
,那么一切都很好。
另一方面,如果我回答too many
,不会笑我的笑话。 相反,我得到这个(如预期):
Exception in thread "main" java.util.InputMismatchException at java.util.Scanner.throwFor(Scanner.java:819) at java.util.Scanner.next(Scanner.java:1431) at java.util.Scanner.nextInt(Scanner.java:2040) at java.util.Scanner.nextInt(Scanner.java:2000) at In.main(In.java:9)
有没有办法让它忽略那些没有ints的条目,或者用“有多less入侵? 我想知道如何做到这一点。
您可以使用Scanner
用于预validation的众多hasNext*
方法之一。
if (in.hasNextInt()) { int a = in.nextInt() ; System.out.println(a); } else { System.out.println("Sorry, couldn't understand you!"); }
这可以防止InputMismatchException
被抛出,因为在读取之前,您总是确保它会匹配。
java.util.Scanner API
-
boolean hasNextInt()
:如果此扫描器input中的下一个标记可以使用nextInt()
方法解释为默认基数中的整型值,则返回true
。 扫描仪不会超过任何input。 -
String nextLine()
:使此扫描器前进到当前行,并返回被跳过的input。
请记住粗体部分。 hasNextInt()
不会超越任何input。 如果返回true
,则可以通过调用nextInt()
来推进扫描器,而不会抛出InputMismatchException
。
如果它返回false
,那么你需要跳过“垃圾”。 最简单的方法是调用nextLine()
,可能两次,但至less一次。
为什么你可能需要做nextLine()
两次,如下所示:假设这是input的input:
42[enter] too many![enter] 0[enter]
假设扫描仪在input的开始处。
-
hasNextInt()
为true,nextInt()
返回42
; 扫描仪现在就在第一个[enter]
。 -
hasNextInt()
为false,nextLine()
返回空string,nextLine()
返回"too many!"
; 扫描仪现在在第二个[enter]
。 -
hasNextInt()
为true,nextInt()
返回0
; 扫描仪现在就在第三个[enter]
。
这是把这些东西放在一起的一个例子。 您可以尝试使用它来研究Scanner
如何工作。
Scanner in = new Scanner (System.in) ; System.out.println("Age?"); while (!in.hasNextInt()) { in.next(); // What happens if you use nextLine() instead? } int age = in.nextInt(); in.nextLine(); // What happens if you remove this statement? System.out.println("Name?"); String name = in.nextLine(); System.out.format("[%s] is %d years old", name, age);
假设input是:
He is probably close to 100 now...[enter] Elvis, of course[enter]
然后输出的最后一行是:
[Elvis, of course] is 100 years old
一般来说,我真的很不喜欢使用相同的库调用来读取和parsing。 语言图书馆似乎非常不灵活,往往不能屈服于你的意愿。
从System.in中提取数据的第一步不应该是失败的,所以它将它作为一个string读入一个variables,然后将该stringvariables转换为一个int。 如果转换失败,很好 – 打印错误并继续。
当你用一些可以抛出exception的东西包装你的stream时,它会让整个混乱离开你的stream的状态变得混乱。
当发生错误的时候,让应用程序抛出一个错误,反对防止错误的发生,这总是一个好处。
一种替代方法是将代码包装在InputMismatchException
的try {...}
catch {...}
块中。 您可能还想要将代码封装在一个while
循环中,让Scanner
保持提示状态,直到满足特定的条件。