使用java.util.Scanner验证输入 [英] Validating input using java.util.Scanner

查看:143
本文介绍了使用java.util.Scanner验证输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 java.util.Scanner System.in 获取用户输入。我需要验证以下内容的输入:

I'm taking user input from System.in using a java.util.Scanner. I need to validate the input for things like:


  • 必须是非负数

  • 必须是按字母顺序排列的字母

  • ...等

什么是最好的方法这样做?

What's the best way to do this?

推荐答案

概述Scanner.hasNextXXX 方法



java.util.Scanner 有许多 hasNextXXX 方法,可用于验证输入。以下是所有这些内容的简要概述:

Overview of Scanner.hasNextXXX methods

java.util.Scanner has many hasNextXXX methods that can be used to validate input. Here's a brief overview of all of them:


  • hasNext() - 是否有任何令牌?

  • hasNextLine() - 是否有另一行输入?

  • 对于Java原语

    • hasNext() - does it have any token at all?
    • hasNextLine() - does it have another line of input?
    • For Java primitives
      • hasNextInt() - does it have a token that can be parsed into an int?
      • Also available are hasNextDouble(), hasNextFloat(), hasNextByte(), hasNextShort(), hasNextLong(), and hasNextBoolean()
      • As bonus, there's also hasNextBigInteger() and hasNextBigDecimal()
      • The integral types also has overloads to specify radix (for e.g. hexadecimal)
      • hasNext(String pattern)
      • hasNext(Pattern pattern) is the Pattern.compile overload

      扫描仪能够提供更多功能,因为它是基于正则表达式的。一个重要的特征是 useDelimiter(字符串模式) ,可让您定义模式分隔您的标记的内容。还有 find 跳过 c $ c> 忽略分隔符的方法。

      Scanner is capable of more, enabled by the fact that it's regex-based. One important feature is useDelimiter(String pattern), which lets you define what pattern separates your tokens. There are also find and skip methods that ignores delimiters.

      以下讨论将使正则表达式尽可能简单,因此重点仍然是扫描程序

      The following discussion will keep the regex as simple as possible, so the focus remains on Scanner.

      以下是使用的简单示例hasNextInt()从输入验证正 int

      Here's a simple example of using hasNextInt() to validate positive int from the input.

      Scanner sc = new Scanner(System.in);
      int number;
      do {
          System.out.println("Please enter a positive number!");
          while (!sc.hasNextInt()) {
              System.out.println("That's not a number!");
              sc.next(); // this is important!
          }
          number = sc.nextInt();
      } while (number <= 0);
      System.out.println("Thank you! Got " + number);
      

      这是一个示例会话:


      请输入正数!

      five

      这不是号码!

      -3

      请输入正数!

      5

      谢谢!得到5

      Please enter a positive number!
      five
      That's not a number!
      -3
      Please enter a positive number!
      5
      Thank you! Got 5

      注意多么容易 Scanner.hasNextInt()比较详细 try / catch Integer.parseInt / NumberFormatException 组合。按合同,扫描器 保证如果 hasNextInt(),那么 nextInt()将和平地给你 int 不会抛出任何 NumberFormatException / InputMismatchException / NoSuchElementException

      Note how much easier Scanner.hasNextInt() is to use compared to the more verbose try/catch Integer.parseInt/NumberFormatException combo. By contract, a Scanner guarantees that if it hasNextInt(), then nextInt() will peacefully give you that int, and will not throw any NumberFormatException/InputMismatchException/NoSuchElementException.

      • How to use Scanner to accept only valid int as input
      • How do I keep a scanner from throwing exceptions when the wrong type is entered? (java)

      请注意,上面的代码段包含 sc.next()用于推进扫描器的语句,直到 hasNextInt()。重要的是要意识到 hasNextXXX 方法的 none 推进 扫描仪 通过任何输入!你会发现如果从代码片段中省略这一行,那么它会在无效输入上进入无限循环!

      Note that the snippet above contains a sc.next() statement to advance the Scanner until it hasNextInt(). It's important to realize that none of the hasNextXXX methods advance the Scanner past any input! You will find that if you omit this line from the snippet, then it'd go into an infinite loop on an invalid input!

      这有两个结果:


      • 如果你需要跳过垃圾输入如果您的 hasNextXXX 测试失败,那么您需要以某种方式推进扫描仪(例如 next() nextLine() skip 等。)

      • 如果一个 hasNextXXX 测试失败,你可以仍然测试它是否 hasNextYYY

      • If you need to skip the "garbage" input that fails your hasNextXXX test, then you need to advance the Scanner one way or another (e.g. next(), nextLine(), skip, etc).
      • If one hasNextXXX test fails, you can still test if it perhaps hasNextYYY!

      以下是执行多个 hasNextXXX 测试的示例。

      Here's an example of performing multiple hasNextXXX tests.

      Scanner sc = new Scanner(System.in);
      while (!sc.hasNext("exit")) {
          System.out.println(
              sc.hasNextInt() ? "(int) " + sc.nextInt() :
              sc.hasNextLong() ? "(long) " + sc.nextLong() :  
              sc.hasNextDouble() ? "(double) " + sc.nextDouble() :
              sc.hasNextBoolean() ? "(boolean) " + sc.nextBoolean() :
              "(String) " + sc.next()
          );
      }
      

      这是一个示例会话:


      5

      (int)5

      false

      (布尔值)false

      blah

      (String)blah

      1.1

      (双倍)1.1

      100000000000

      (长)100000000000

      退出

      5
      (int) 5
      false
      (boolean) false
      blah
      (String) blah
      1.1
      (double) 1.1
      100000000000
      (long) 100000000000
      exit

      请注意,测试的顺序很重要。如果扫描仪 hasNextInt(),那么它还 hasNextLong(),但它不一定是 true 反之亦然。通常情况下,您希望在更一般的测试之前进行更具体的测试。

      Note that the order of the tests matters. If a Scanner hasNextInt(), then it also hasNextLong(), but it's not necessarily true the other way around. More often than not you'd want to do the more specific test before the more general test.

      扫描仪具有正则表达式支持的许多高级功能。以下是使用它来验证元音的示例。

      Scanner has many advanced features supported by regular expressions. Here's an example of using it to validate vowels.

      Scanner sc = new Scanner(System.in);
      System.out.println("Please enter a vowel, lowercase!");
      while (!sc.hasNext("[aeiou]")) {
          System.out.println("That's not a vowel!");
          sc.next();
      }
      String vowel = sc.next();
      System.out.println("Thank you! Got " + vowel);
      

      这是一个示例会话:


      请输入元音,小写!

      5

      这不是元音!

      z

      这不是元音!
      $ b $是

      谢谢!得到

      Please enter a vowel, lowercase!
      5
      That's not a vowel!
      z
      That's not a vowel!
      e
      Thank you! Got e

      在正则表达式中,作为Java字符串文字,模式 [aeiou]就是所谓的角色类;它匹配任何字母 a e i o u 。请注意,使上述测试不区分大小写非常简单:只需为 Scanner 提供此类正则表达式模式。

      In regex, as a Java string literal, the pattern "[aeiou]" is what is called a "character class"; it matches any of the letters a, e, i, o, u. Note that it's trivial to make the above test case-insensitive: just provide such regex pattern to the Scanner.

      • hasNext(String pattern) - Returns true if the next token matches the pattern constructed from the specified string.
      • java.util.regex.Pattern
      • Java Tutorials/Essential Classes/Regular Expressions
      • regular-expressions.info/Character Classes

      有时你需要逐行扫描,一行上有多个令牌。完成此操作的最简单方法是使用两个 扫描程序,其中第二个扫描程序需要第一个 Scanner 中的 nextLine()作为输入。这是一个例子:

      Sometimes you need to scan line-by-line, with multiple tokens on a line. The easiest way to accomplish this is to use two Scanner, where the second Scanner takes the nextLine() from the first Scanner as input. Here's an example:

      Scanner sc = new Scanner(System.in);
      System.out.println("Give me a bunch of numbers in a line (or 'exit')");
      while (!sc.hasNext("exit")) {
          Scanner lineSc = new Scanner(sc.nextLine());
          int sum = 0;
          while (lineSc.hasNextInt()) {
              sum += lineSc.nextInt();
          }
          System.out.println("Sum is " + sum);
      }
      

      这是一个示例会话:


      在一行(或退出)中给我一堆数字

      3 4 5

      总和为12

      10 100百万美元

      总和是110

      等什么?

      总和为0

      退出

      Give me a bunch of numbers in a line (or 'exit')
      3 4 5
      Sum is 12
      10 100 a million dollar
      Sum is 110
      wait what?
      Sum is 0
      exit

      除了 Scanner(String) 构造函数,还有 扫描仪(java.io.File) 等。


      • 扫描仪提供丰富的功能,例如 hasNextXXX 验证方法。

      • 正确使用 hasNextXXX / nextXXX 组合意味着扫描仪从不抛出 InputMismatchException / NoSuchElementException

      • 始终请记住, hasNextXXX 不会超过任何输入扫描仪

      • Don如果有必要,不要创建多个扫描器。两个简单的扫描程序通常比一个过于复杂的扫描程序好。

      • 最后即使您没有任何计划使用高级正则表达式功能,请记住哪些方法是基于正则表达式的,哪些不是。采用字符串模式参数的任何 Scanner 方法都是基于regex的。


        • 提示:将任何字符串转换为文字的简便方法模式是 Pattern.quote 它。

        • Scanner provides a rich set of features, such as hasNextXXX methods for validation.
        • Proper usage of hasNextXXX/nextXXX in combination means that a Scanner will NEVER throw an InputMismatchException/NoSuchElementException.
        • Always remember that hasNextXXX does not advance the Scanner past any input.
        • Don't be shy to create multiple Scanner if necessary. Two simple Scanner is often better than one overly complex Scanner.
        • Finally, even if you don't have any plans to use the advanced regex features, do keep in mind which methods are regex-based and which aren't. Any Scanner method that takes a String pattern argument is regex-based.
          • Tip: an easy way to turn any String into a literal pattern is to Pattern.quote it.

          这篇关于使用java.util.Scanner验证输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆