【问题标题】:Validating input using java.util.Scanner [duplicate]使用 java.util.Scanner 验证输入 [重复]
【发布时间】:2026-01-12 21:40:01
【问题描述】:

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

  • 必须是非负数
  • 必须是字母
  • ...等

最好的方法是什么?

【问题讨论】:

  • 您的许多问题都采用这样的形式:措辞不当,要求其他人发布代码,而您没有展示您自己做了什么(或尝试过)。这不是学习新事物的方法。弄脏你的手!自己尝试几件事,当卡在某个地方时,在此处发布一个特定问题(并发布不起作用的代码)。我向你保证,这样做,你会得到比这些近距离投票更好的回应。
  • @Bart K:如果为了改进问题以使其值得重新打开,我对其进行编辑以询问如何使用Scanner 验证输入,这对其他回答者是否公平?根据 OP 之前的 Q,似乎 Scanner 是 OP 正在使用的。
  • @polygenelubricants,是的,如果问题被改写以便更有意义,我会投票重新开放。如果这个问题从长远来看会被删除(以及所有好的答案(主要是你的)),那将是一种耻辱。当然,我曾希望@bhavna 会尝试自己改进它……
  • @Bart K:编辑完成。还将进一步改进我的答案。如果其他回答者认为这不公平,请向他们道歉。
  • 难以置信的是,这个问题已经收集了2个删除票。重新打开。

标签: java validation java.util.scanner


【解决方案1】:

Scanner.hasNextXXX 方法概述

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

Scanner 具有更多功能,因为它基于正则表达式。一个重要的特性是useDelimiter(String pattern),它可以让你定义什么pattern 分隔你的标记。还有findskip 方法忽略 分隔符。

以下讨论将使正则表达式尽可能简单,因此重点仍然是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);

这是一个示例会话:

请输入一个正数!

这不是一个数字!
-3
请输入一个正数!
5
谢谢!得到 5 个

请注意,与更冗长的 try/catch Integer.parseInt/NumberFormatException 组合相比,Scanner.hasNextInt() 的使用要容易得多。根据合同,Scanner保证如果它是hasNextInt(),那么nextInt() 将和平地给你int,并且不会抛出任何NumberFormatException /InputMismatchException/NoSuchElementException.

相关问题


示例 2:多个hasNextXXX 在同一个令牌上

请注意,上面的 sn-p 包含一个 sc.next() 语句以将 Scanner 推进到 hasNextInt()。重要的是要意识到没有一个 hasNextXXX 方法会推进 Scanner 超过任何输入!你会发现,如果你在 sn-p 中省略这一行,那么它会在输入无效时进入无限循环!

这有两个后果:

  • 如果您需要跳过未通过hasNextXXX 测试的“垃圾”输入,则需要以一种或另一种方式推进Scanner(例如next()nextLine()skip 等) .
  • 如果一个hasNextXXX 测试失败,您可以仍然测试它是否可能是hasNextYYY

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

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

(布尔)假
废话
(字符串)废话
1.1
(双) 1.1
100000000000
(长)100000000000
退出

请注意,测试的顺序很重要。如果是ScannerhasNextInt(),那么它也是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
那不是元音!
电子
谢谢!明白了

在正则表达式中,作为Java 字符串文字,模式"[aeiou]" 就是所谓的“字符类”;它匹配任何字母aeiou。请注意,使上述测试不区分大小写是微不足道的:只需将此类正则表达式模式提供给 Scanner

API 链接

相关问题

参考文献


示例 4:一次使用两个 Scanner

有时您需要逐行扫描,一行上有多个标记。最简单的方法是使用 two Scanner,其中第二个 Scanner 将来自第一个 ScannernextLine() 作为输入。这是一个例子:

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
退出

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


总结

  • Scanner 提供了一组丰富的功能,例如用于验证的hasNextXXX 方法。
  • 正确组合使用hasNextXXX/nextXXX 意味着Scanner绝不抛出InputMismatchException/NoSuchElementException
  • 永远记住hasNextXXX 不会使Scanner 超过任何输入。
  • 如有必要,不要害羞地创建多个Scanner。两个简单的Scanner 通常比一个过于复杂的Scanner 要好。
  • 最后,即使您没有任何使用高级正则表达式功能的计划,请记住哪些方法是基于正则表达式的,哪些不是。任何采用String pattern 参数的Scanner 方法都是基于正则表达式的。
    • 提示:将任何String 转换为文字模式的简单方法是Pattern.quote it。

【讨论】:

  • 此代码适用于负数,但不适用于字母
  • 当然,这可能是最好的方法,具体取决于输入法。
  • @bhavna:从代码中学习,其余的自己做。
  • @bhavna,请不要指望其他人来完成所有您的工作。此外,不时感谢某人也不会受到伤害。
  • 我喜欢 hasNextInt()。我一直在处理 NumberFormatException 因为我没有阅读足够的文档。哎哟。谢谢你提供的详情。也很好的例子。
【解决方案2】:

这是一种极简的方式。

System.out.print("Please enter an integer: ");
while(!scan.hasNextInt()) scan.next();
int demoInt = scan.nextInt();

【讨论】:

    【解决方案3】:

    为了检查字符串中的字母,您可以使用正则表达式,例如:

    someString.matches("[A-F]");
    

    为了检查数字和阻止程序崩溃,我有一个非常简单的类,您可以在下面找到您可以在其中定义所需值的范围。 Here

        public int readInt(String prompt, int min, int max)
        {
        Scanner scan = new Scanner(System.in);
    
        int number = 0;
    
        //Run once and loop until the input is within the specified range.
        do 
        {
            //Print users message.
            System.out.printf("\n%s > ", prompt);
    
            //Prevent string input crashing the program.
            while (!scan.hasNextInt()) 
            {
                System.out.printf("Input doesn't match specifications. Try again.");
                System.out.printf("\n%s > ", prompt);
                scan.next(); 
            }
    
            //Set the number.
            number = scan.nextInt();
    
            //If the number is outside range print an error message.
            if (number < min || number > max)
                System.out.printf("Input doesn't match specifications. Try again.");
    
        } while (number < min || number > max);
    
        return number;
    }
    

    【讨论】:

      【解决方案4】:

      一个想法:

      try {
          int i = Integer.parseInt(myString);
          if (i < 0) {
              // Error, negative input
          }
      } catch (NumberFormatException e) {
          // Error, not a number.
      }
      

      还有,在commons-lang 库中,CharUtils 类提供方法isAsciiNumeric() 来检查字符是否为数字,isAsciiAlpha() 来检查字符是否为字母...

      【讨论】:

        【解决方案5】:

        如果您从控制台或类似工具解析字符串数据,最好的方法是使用正则表达式。在此处阅读更多信息: http://java.sun.com/developer/technicalArticles/releases/1.4regex/

        否则,要从字符串中解析 int,请尝试 Integer.parseInt(string)。如果字符串不是数字,则会出现异常。否则,您可以对该值进行检查以确保它不是负数。

        String input;
        int number;
        try
        {
            number = Integer.parseInt(input);
            if(number > 0)
            {
                System.out.println("You positive number is " + number);
            }
        } catch (NumberFormatException ex)
        {
             System.out.println("That is not a positive number!");
        }
        

        要获得仅包含字符的字符串,您可能最好循环遍历每个字符以检查数字,例如使用 Character.isLetter(char)

        String input
        for(int i = 0; i<input.length(); i++)
        {
           if(!Character.isLetter(input.charAt(i)))
           {
              System.out.println("This string does not contain only letters!");
              break;
           }
        }
        

        祝你好运!

        【讨论】:

          【解决方案6】:

          我尝试的是,首先我接受整数输入并检查它是否为负数,如果它为负数,然后再次接受输入

          Scanner s=new Scanner(System.in);
          
              int a=s.nextInt();
              while(a<0)
              {
              System.out.println("please provide non negative integer input ");
              a=s.nextInt();
              }
              System.out.println("the non negative integer input is "+a);
          

          这里,你需要先接受字符输入,然后检查用户是否给了字符,如果没有再接受字符输入

              char ch = s.findInLine(".").charAt(0);
              while(!Charcter.isLetter(ch))
              {
              System.out.println("please provide a character input ");
              ch=s.findInLine(".").charAt(0);
              }
              System.out.println("the character  input is "+ch);
          

          【讨论】:

          • 不仅仅是发布一些代码。解释为什么该代码是问题的答案。尤其是在最初的问题之后的 7 年。
          • 我只是想补充一下我的观察......如果有人会来这里,他会看到解决方案......他不会看到时间......就像我来到这里......你需要理解我的代码......我尝试过的是首先我接受整数输入并检查它是否为负,如果它为负而不是再次接受输入,第二部分是你需要接受先输入字符,然后检查用户是否给了字符,如果没有,则再次输入字符