验证字符是否为特定字母



我正在尝试编写一个测试程序来测试数字序列是否是魔方。但是,我正在尝试弄清楚如何正确验证用户输入。简而言之,我想提示用户输入一个整数并继续这样做,直到他们输入字母"x"。如果他们在完成之前不小心输入了一个字母而不是 x,我希望程序在允许他们继续输入直到输入 x 之前给他们一个简短的错误。

这是我现在拥有的:

public class TestSquare
{
   public static void main(String [] args)
   {
      Square numbers = new Square();
      Scanner in = new Scanner(System.in);
      System.out.println("Enter an integer(x to exit): ");
      int i = in.nextInt();
      char c = (char)(i + '0');
      while(Character.isDigit(c))
      {
         numbers.add(i);
         System.out.println("Enter an integer(x to exit): ");
         i = in.nextInt();
         c = (char)(i + '0');
      }
      if( c == 'x')
      {
         numbers.isSquare();
         numbers.isUnique();
         numbers.isMagic();
      }
      else
      {
         System.out.println("***Invalid Data Entry. Please Try Again or enter x to exit.***");
         i = in.nextInt();
         c = (char)(i + '0');
      }
   }
}

这让我可以连续输入整数,但是当我输入一个字母(包括x(时,程序会遇到错误并停止。

while (Character.isDigit(c)) {
            numbers.add(i);
            try {
                System.out.println("Enter an integer(x to exit): ");
                i = in.nextInt();
                c = (char) (i + '0');
            } catch (java.util.InputMismatchException e) {
              if (c == 'x') {
                numbers.isSquare();
                numbers.isUnique();
                numbers.isMagic();
                System.exit(0);
            } else {
                System.out.println("***Invalid Data Entry. Please Try Again or enter x to exit.***");
                in = new Scanner(System.in);
                continue;
            }
            }
        }

我在 while 循环中添加了一个尝试和捕获块。因此,如果用户输入一个字符,程序将不会崩溃。相反,控制权将转到捕获块。在这里,您可以检查不是整数的输入是否是字符 x。如果是,您可以使用System.exit(0);停止执行,如果不是,则可以继续该过程。

无法检查是否c == 'x',因为您期望用户提供 int,并且如果用户输入除 int 以外的任何内容,则会抛出异常。但是没有办法找出来自用户的输入是什么。若要避免此问题,可以让用户输入其他整数以退出。也许-1。

tl;dr

仅当您确定输入将用作int时,才使用 Scanner.nextInt() 。将Scanner.next()用于纯String值。


回答这个问题的关键是了解代码在类型之间的转换位置:Stringintchar。(保持非常清楚这些东西需要练习,但这是值得的:当你对类型有很好的了解时,发现问题要容易得多!

类型

int 类型是一种整数,可以保存低至 -

2,000,000,000 和高达 2,000,000,000 的值。

char 类型是一种不同类型的整数,可以保存从 0 到大约 65,000 的值,但这些值通常用于对文本字符进行编码:'A' 为 65,'B'为 66,'X'为 88,'x'为 120。

String 类型是在一行中保存一系列文本字符的对象。它对于像 "Hello" 这样的东西很有用,但即使字符看起来是数字,String也是String"100" 是一个包含三个字符的String

  • 4 是值为 4 的int
  • '4' 是值为 52 的char
  • "4" 是长度为 1 的String"4"中的第一个字符是 '4'

正数个位数

Enter an integer(x to exit):
4

当您在键盘上键入数字 4 并按 Enter 时,这实际上还不是intjava.util.Scanner会将其视为字符串令牌。(为了简单起见,我不会谈论System.input看到它或Scanner如何找到令牌。

int i = in.nextInt();

java.util.Scanner nextInt() 方法将该String令牌 ("4"( 解析为int (4(。

然后,发布的代码采用该int (4( 并将其转换为char ('4'(:

char c = (char) (i + '0');

这会将int类型的整数添加到char类型的整数。在我们的例子中,由于i是 4,'0'是 48,程序会计算4 + 48 = 52并将该数字 52 存储在名为 cchar插槽中。(幸运的是,这些数字足够小,适合。

因此,当输入流中的下一个String标记被"4"时,代码将运行两行:

int i = in.nextInt(); // "4" converted to 4
char c = (char) (i + '0'); // 4 converted to '4'

目前为止,一切都好。

一个字母

Enter an integer(x to exit):
x

当您在键盘上键入字母 x 并按 Enter 时,故事会短得多。

下一个令牌是 String "x"Scanner方法nextInt()读取令牌并尝试将其解析为int,但"x"不符合格式,因此nextInt()抛出InputMismatchException异常。

异常意味着程序中断正常的运行流程,将所有变量留在原处,并直接跳转到最接近匹配的catch块。当没有匹配的catch块可以跳转到时,Java 的默认块将启动:打印异常,中止程序。

因此,当输入流中的下一个String标记被"x"时,代码运行一行并在任何变量更改之前跳转:

i = in.nextInt(); // throws exception, so i does not change
c = (char) (i + '0'); // never executed, so c does not change

关键要点是,Scanner.nextInt()只能帮助您像"400"一样处理文本,而不会帮助您像"x"一样处理文本。

还有什么?

Scanner类的方法比nextInt()多得多。还有另外两种方法与此情况特别相关:

  • hasNextInt()(当下一个令牌为"400"时truefalse当下一个令牌为"hello"(时
  • (
  • next()(给你下一个令牌(

普通的,next() ,是最重要的 - 它自己返回下一个String令牌。没有额外的转换。所以如果下一个令牌是"4"next()会返回"4"。如果下一个令牌"x"next()将返回"x"

如果你想将输入处理为文本 - 也就是说,如果你想将"x"与"a"或"hello"区别对待,那就是使用:

String token = in.next();
if (token.equals("x")) {
  System.out.println("Goodbye");
}

事实上,nextInt()本质上是next()的捷径,后跟Integer.parseInt()

你有力量

有了对类型和转换的新、更清晰的理解,您可能对如何处理各种格式的输入有一些想法。

也许您的新结构可能看起来像这样的伪代码:

while there are more tokens available {
    is the next token suitable for integer parsing? {
        parse the next token as an integer
    } else {
        deal with the token in its plain string form
    }
}

或者,也许您会决定实际上根本不需要使用int,而字符串"4"足以满足您的目的。或者,也许您可以直接从"4"转换为"4"。

世界是你的牡蛎!


奖金回合

在处理新代码时,您可能会发现以下一些提示很有帮助:

  • "hello".charAt(0) == 'h'
  • "400".charAt(0) == '4'
  • Integer.parseInt("400", 10) == 400

如果您确实想确保将类型放在正确的位置,请考虑以下情况:

  • "400"(多位数字(
  • "-400"(负数(
  • "400000"(适合int整数,不适合char整数(
  • "4x"(数字和非数字一起(
  • "4 0 0"(一起输入的单独令牌(

祝你好运!

最新更新