【问题标题】:How can I verify the int length of scanner input?如何验证扫描仪输入的 int 长度?
【发布时间】:2017-03-09 00:22:07
【问题描述】:

我能够让程序运行并使用错误检查来确保用户输入实际上是一个 int。我遇到的问题是我只希望它是一个 3 位数的整数。我无法将它放到正确的位置:

import java.util.*;

public class listMnemonics

{

   public static void main(String[] args)

   {

   //Defines the "keypad" similar to that of a phone
   char[][] letters = 

   {{'0'},{'1'},{'A','B','C'},{'D','E','F'},{'G','H','I'},{'J','K','L'}, 
   {'M','N','O'},{'P','Q','R','S'},{'T','U','V'},{'W','X','Y','Z'}};

     //Creates the Scanner
     Scanner scan = new Scanner(System.in);

这就是我需要实现它的地方,我遇到了这个问题。我敢肯定,这可能只是我需要的一条线不合适或缺少,我只是不知道是什么或在哪里。当它坐着时,它会不断地要求我输入一个 3 位数的数字,无论长度如何。对输入的字符串进行错误检查目前有效:

     //Gives instructions to the user to enter 3-digit number
     //Any amount of numbers will work, but instructions help
     //System.out.println("Please enter a 3-digit number: ");

     int j;


     do
     {
     System.out.println("Please enter a 3-digit number: ");

           while (!scan.hasNextInt()) {

     System.out.println("That's not a 3-digit number! Try again!");
     scan.next(); // this is important!
     }

     j = scan.nextInt();

     }



     //while (j <= 0); This works while not checking digit length
     while (j != 3);
     int w = (int) Math.log10(j) +1; //Found this, but not sure if it helps or not

     String n = Integer.toString(w);

剩下的就是做我需要做的事情了:

     //Determines char length based on user input
     char[][] sel = new char[n.length()][];

     for (int i = 0; i < n.length(); i++)

     {

        //Grabs the characters at their given position
        int digit = Integer.parseInt("" +n.charAt(i));
        sel[i] = letters[digit];

     }

  mnemonics(sel, 0, "");

}

public static void mnemonics(char[][] symbols, int n,  String s) 

{

  if (n == symbols.length)

  {

     System.out.println(s);
     return;

  }

  for (int i = 0; i < symbols[n].length; i ++) 

  {

     mnemonics(symbols, n+1, s + symbols[n][i]);

  }
 }
}

这是输出:

----jGRASP exec: java listMnemonics
请输入 3 位数字:
2345
请输入 3 位数字:
12
请输入 3 位数字:
123
请输入 3 位数字:
motu
这不是一个三位数的数字!再试一次!

【问题讨论】:

  • 前导零有可能吗? nbr &gt; 99 &amp;&amp; nbr &lt; 1000 怎么了?
  • 是的,前导或结尾的零是可接受的输入。如果是这样的话,我应该把那条线放在哪里?那是我的麻烦。
  • 如果是这种情况,您无法将其解析为int。您必须将其作为字符串读入并自己解析。
  • 所以你说的是:int j; 我应该改成String j = scan.nextLine(); 或类似的东西,然后从那里开始?
  • 无论如何我都不是 java 专家,大多数时候我只是很幸运,但这听起来我可能需要进行比预期更多的更改,因为在输入之后我目前正在解析intString,然后继续前进。我不希望 String 成为可接受的输入。

标签: java math input int java.util.scanner


【解决方案1】:

在 MvG 和 pingul 的帮助下,这就是目前我希望的工作方式:

import java.util.*;
import java.util.regex.Pattern;

public class listMnemonics

{

   public static void main(String[] args)

{

   // Defines the "keypad" similar to that of a phone
   char[][] letters = 

   {{'0'},{'1'},{'A','B','C'},{'D','E','F'},{'G','H','I'},{'J','K','L'}, 
   {'M','N','O'},{'P','Q','R','S'},{'T','U','V'},{'W','X','Y','Z'}};

      // Creates the Scanner
      Scanner scan = new Scanner(System.in);

      // Gives instructions to the user to enter 3-digit number
      // This 'Pattern' also guarantees that only 3 digits works.

      Pattern threeDigitNumber = Pattern.compile("[0-9]{3}");

      int j;

      do

      {

         System.out.println("Please enter a 3-digit phone number: ");

         // If it's not a 3-digit int, try again
         while (!scan.hasNext(threeDigitNumber)) 

            {

            System.out.println("That's not a 3-digit number! Try again!");

            // This is important!
            scan.next(); 

            }

         j = scan.nextInt();

      }

      while (j <= 0);

      String n = Integer.toString(j);


      // Determines char length based on user input
      char[][] sel = new char[n.length()][];

      for (int i = 0; i < n.length(); i++)

      {

         // Grabs the characters at their given position
         int digit = Integer.parseInt("" +n.charAt(i));
         sel[i] = letters[digit];

      }

   mnemonics(sel, 0, "");

}

// Here is where the magic happens and creates the possible
// letter combinations based on the user input and characters
// selected in previous steps.
public static void mnemonics(char[][] symbols, int n,  String s) 

{

   if (n == symbols.length)

   {

      System.out.println(s);
      return;

   }

   for (int i = 0; i < symbols[n].length; i ++) 

   {

      mnemonics(symbols, n+1, s + symbols[n][i]);

   }
 }
}

【讨论】:

    【解决方案2】:

    压缩并重新格式化您的代码读取

    Scanner scan = new Scanner(System.in);
    int j;
    do {
      System.out.println("Please enter a 3-digit number: ");
      while (!scan.hasNextInt()) {
         System.out.println("That's not a 3-digit number! Try again!");
         scan.next(); // this is important!
       }
       j = scan.nextInt();
    } while (j != 3);
    

    the Scanner documentation 相比,我们可以看到scan.next() 调用将读取(并丢弃)非整数令牌。否则 j 将是您读取的整数。当你读到的数字与 3 不同时,你继续这样做。不是数字的长度,而是数字本身。所以如果你想结束循环,输入3。如果您想按照提示执行此操作,请输入003

    如果这不是您要检查的内容,请更改循环结束条件。或者也许改变您测试三位数字的方式,通过使用正则表达式来匹配这些数字。

    Scanner scan = new Scanner(System.in);
    Pattern threeDigitNumber = Pattern.compile("\\d\\d\\d");
    int j;
    System.out.println("Please enter a 3-digit number: ");
    while (!scan.hasNext(threeDigitNumber)) {
      if (scan.hasNext()) {
        System.out.println(scan.next() + " is not a 3-digit number! Try again!");
      } else {
        System.out.println("Input terminated unepxectedly");
        System.exit(1);
      }
    }
    j = scan.nextInt();
    

    正如 cmets 正确指出的那样,模式 "\\d\\d\\d" 也可以写成 "[0-9]{3}""\\d{3}""[0-9][0-9][0-9]"。在位数是变量的情况下,使用 {…} 可能很有用。

    documentation for Scanner.hasNext(Pattern) 需要模式来匹配输入。这显然遵循将整个字符串与模式匹配的Matcher.matches() 语义,而不是检查字符串是否包含与模式匹配的任何部分的Matcher.find()。所以输入不必像我最初假设的那样包含在^$ 中,实际上不应该使用这些,除非模式是用Pattern.MULTILINE flag 编译的。

    您可能想调用Scanner.useDelimiter 以仅使用换行符进行分隔。

    Scanner.useDelimiter("[\\r\\n]+")
    

    【讨论】:

    • 啊,好的。我知道那在做什么。当我运行程序并输入 3 时,它会打印 1 作为输出。我会删除它。好像没什么用。
    • @motu:我更新了我的答案,包括关于如何满足您的需求的建议。
    • 是的,太棒了,谢谢。我认为这让我走上了正确的轨道。我现在遇到的问题是,即使我输入了一个 3 位数字,它也不起作用。它只是不断要求输入。
    • [UPDATE] @MvG 使用 Pattern 类,当我运行程序并在第一次尝试时输入一个 3 位数字时,它可以工作。如果我运行程序并输入一个字符串或任何不是 3 位的数字,当我最终输入 3 位时,它不起作用。
    • [更新] @MvG 我明白了!我将您的:Pattern.compile("^\\d\\d\\d$"); 更改为:Pattern.compile("[0-9]{0,3}");,这样就成功了!
    猜你喜欢
    • 2020-03-29
    • 2018-05-30
    • 1970-01-01
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-20
    相关资源
    最近更新 更多