【问题标题】:How do I keep a Scanner from throwing exceptions when the wrong type is entered?当输入错误的类型时,如何防止 Scanner 引发异常?
【发布时间】:2011-01-30 13:47:07
【问题描述】:

下面是一些示例代码:

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

如果我运行程序并给它一个int 就像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)

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

【问题讨论】:

    标签: java text-parsing java.util.scanner


    【解决方案1】:

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

    另一种方法是将代码包装在try {...} catch {...} 块中,用于InputMismatchException。 您可能还希望将代码包装在 while 循环中,以使 Scanner 不断提示,直到满足特定条件。

    【讨论】:

    • 你应该移动“found=true;”到 try 语句的顶部。现在它总是正确的
    • 我省略了我的示例,我觉得它看起来不对。我只是想给出要点:您应该捕获正在抛出的错误,而不是解决它们以及“重新提示”的技术。无论如何,谢谢 Kurresmack。
    • try catch 块究竟是如何工作的?我以前从未使用过。
    • 我正在使用手机,我会尽力而为。 try { // code here } catch(InputMismatchException e) { // catch wrong format }
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      您可以使用Scanner 具有的众多hasNext* 方法之一进行预验证。

          if (in.hasNextInt()) {
              int a = in.nextInt() ; 
              System.out.println(a);
          } else {
              System.out.println("Sorry, couldn't understand you!");
          }
      

      这甚至可以防止InputMismatchException 被抛出,因为您在阅读之前始终确保它WILL匹配。


      java.util.Scanner API

      • boolean hasNextInt():如果此扫描器输入中的下一个标记可以使用 nextInt() 方法解释为默认基数中的 int 值,则返回 true扫描仪不会超过任何输入。

      • 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
      

      【讨论】:

      • 这看起来很有希望。您能否明确解释一下 hasNextInt() 的作用?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-17
      • 1970-01-01
      • 2011-06-27
      • 1970-01-01
      • 2015-09-28
      • 2017-12-26
      • 2013-01-30
      相关资源
      最近更新 更多