使用 java.util.Scanner 验证输入[重复]

2023-12-19

我正在接受用户输入System.in用一个java.util.Scanner。我需要验证以下内容的输入:

  • 它必须是一个非负数
  • 它必须是字母
  • ... etc

最好的方法是什么?


大致的了解Scanner.hasNextXXX methods

java.util.Scanner http://java.sun.com/javase/6/docs/api/java/util/Scanner.html有很多hasNextXXX可用于验证输入的方法。以下是所有这些内容的简要概述:

  • hasNext() http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#hasNext%28%29- 有吗any令牌吗?
  • hasNextLine() http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#hasNextLine%28%29- 它还有另一行输入吗?
  • For Java primitives
    • hasNextInt() http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#hasNextInt%28%29- 它是否有一个可以解析为int?
    • 还可以使用的是hasNextDouble() http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#hasNextDouble%28%29, hasNextFloat() http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#hasNextFloat%28%29, hasNextByte() http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#hasNextByte%28%29, hasNextShort() http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#hasNextShort%28%29, hasNextLong() http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#hasNextLong%28%29, and hasNextBoolean() http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#hasNextBoolean%28%29
    • 作为奖励,还有hasNextBigInteger() http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#hasNextBigInteger%28%29 and hasNextBigDecimal() http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#hasNextBigDecimal%28%29
    • 整数类型还具有用于指定基数的重载(例如十六进制)
  • Regular expression-based
    • hasNext(String pattern) http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#hasNext%28java.lang.String%29
    • hasNext(Pattern pattern) http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#hasNext%28java.lang.String%29 is the Pattern.compile http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html#compile%28java.lang.String%29超载

Scanner由于它是基于正则表达式的,因此它具有更多功能。一个重要的特点是useDelimiter(String pattern) http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#useDelimiter%28java.lang.String%29,它可以让您定义什么pattern分隔您的令牌。还有find and skip方法ignores分隔符。

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


示例 1:验证正整数

这是一个简单的使用示例hasNextInt()验证阳性int从输入。

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 个

请注意有多容易Scanner.hasNextInt()是使用相比更冗长的try/catch Integer.parseInt http://java.sun.com/javase/6/docs/api/java/lang/Integer.html#parseInt%28java.lang.String%29/NumberFormatException http://java.sun.com/javase/6/docs/api/java/lang/NumberFormatException.html组合。根据合同,一个Scanner 保证如果它hasNextInt(), then nextInt()会平静地给你int, 还会not扔任何NumberFormatException/InputMismatchException/NoSuchElementException.

相关问题

  • 如何使用 Scanner 只接受有效的 int 作为输入 https://stackoverflow.com/questions/2912817/how-to-use-scanner-to-accept-only-valid-int-as-input
  • 输入错误类型时如何防止扫描仪抛出异常? (java) https://stackoverflow.com/questions/2496239/how-do-i-keep-a-scanner-from-throwing-exceptions-when-the-wrong-type-is-entered

示例 2:多个hasNextXXX同样的道理

请注意,上面的代码片段包含一个sc.next()声明以推进Scanner直到它hasNextInt()。重要的是要认识到这一点none of the hasNextXXX 方法推进 Scanner 过去任何输入!您会发现,如果您从代码片段中省略这一行,那么它将因无效输入而进入无限循环!

这有两个后果:

  • 如果您需要跳过失败的“垃圾”输入hasNextXXX测试,那么你需要推进Scanner以一种或另一种方式(例如next(), nextLine(), skip, etc).
  • If one hasNextXXX测试失败,可以still测试一下是否可能hasNextYYY!

这是执行多个的示例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
(布尔值)假
blah
(字符串)废话
1.1
(双)1.1
100000000000
(长)100000000000
出口

请注意,测试的顺序很重要。如果一个Scanner hasNextInt(),那么它也hasNextLong(),但这并不一定true另一种方式。通常,您希望在更一般的测试之前进行更具体的测试。


示例 3:验证元音

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

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
那不是元音!
e
谢谢你!得到了

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

API链接

  • hasNext(String pattern) http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#hasNext%28java.lang.String%29- 退货true如果下一个标记与从指定字符串构造的模式匹配。
  • java.util.regex.Pattern http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html

相关问题

  • Java中读取单个字符 https://stackoverflow.com/questions/3043306/reading-a-single-char-in-java/

参考

  • Java教程/必备类/正则表达式 http://java.sun.com/docs/books/tutorial/essential/regex/
  • 正则表达式.info/字符类 http://www.regular-expressions.info/charclass.html

示例 4:使用两个Scanner at once

有时您需要逐行扫描,一行上有多个标记。完成此操作的最简单方法是使用two Scanner,其中第二个Scanner采取nextLine()从一开始Scanner作为输入。这是一个例子:

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
等等什么?
Sum is 0
exit

此外Scanner(String) http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#Scanner%28java.lang.String%29构造函数,还有Scanner(java.io.File) http://java.sun.com/javase/6/docs/api/java/util/Scanner.html#Scanner%28java.io.File%29除其他外。


Summary

  • Scanner提供了丰富的功能,例如hasNextXXX验证方法。
  • 正确使用hasNextXXX/nextXXX组合起来意味着Scanner will NEVER扔一个InputMismatchException/NoSuchElementException.
  • 永远记住这一点hasNextXXX不推进Scanner过去任何输入。
  • 不要羞于创建多个Scanner如果需要的话。两个简单的Scanner通常比过于复杂的方法要好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:一种简单的方法来转动任何String变成字面模式是Pattern.quote http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html#quote%28java.lang.String%29 it.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 java.util.Scanner 验证输入[重复] 的相关文章

随机推荐