15

这是一些示例代码:

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) ; 
    } 
}

如果我运行该程序并给它一个intlike 4,那么一切都会好起来的。

另一方面,如果我回答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)

有没有办法让它忽略不是整数的条目或重新提示“有多少正在入侵?” 我想知道如何做到这两个。

4

3 回答 3

20

您可以使用多种hasNext*方法之一Scanner进行预验证。

    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()true如果此扫描仪输入中的下一个标记可以使用该nextInt()方法解释为默认基数中的 int 值,则返回。扫描仪不会超过任何输入。

  • String nextLine():将此扫描器前进到当前行并返回被跳过的输入。

请记住粗体部分。hasNextInt()不超过任何输入。如果它返回true,您可以通过调用来推进扫描仪nextInt(),这不会抛出InputMismatchException.

如果它返回false,那么您需要跳过“垃圾”。最简单的方法就是调用nextLine(),可能两次,但至少一次。

为什么您可能需要执行nextLine()两次以下操作:假设这是输入的输入:

42[enter]
too many![enter]
0[enter]

假设扫描仪位于该输入的开头。

  • hasNextInt()为真,nextInt()返回42;扫描仪现在就在第一个之前[enter]
  • hasNextInt()为假,nextLine()返回一个空字符串,第二个nextLine()返回"too many!";扫描仪现在在第二次之后[enter]
  • hasNextInt()为真,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);

假设输入是:

He is probably close to 100 now...[enter]
Elvis, of course[enter]

那么输出的最后一行是:

[Elvis, of course] is 100 years old
于 2010-03-23T00:48:44.303 回答
2

一般来说,我真的非常不喜欢使用同一个库调用来读取和解析。语言库似乎非常不灵活,而且常常不能随心所欲。

从 System.in 提取数据的第一步应该不会失败,所以让它作为字符串读取到变量中,然后将该字符串变量转换为 int。如果转换失败,很好——打印您的错误并继续。

当你用可能引发异常的东西包装你的流时,它会有点混淆整个混乱让你的流处于什么状态。

于 2010-03-22T23:15:54.223 回答
1

当错误发生时您的应用程序抛出错误总是有好处的,这与阻止它发生的方法相反。

一种替代方法是将代码包装在 for 的try {...} catch {...}块中InputMismatchException。您可能还希望将代码包装在while循环中,以Scanner保持提示直到满足特定条件。

于 2010-03-22T22:33:59.047 回答