如何使Java扫描仪确认空白输入? [英] How to get Java scanner to acknowledge blank input?

查看:79
本文介绍了如何使Java扫描仪确认空白输入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法让我的程序响应空的输入.例如,假设我要提示用户输入类型为BigDecimal的货币值和货币类型.这是有问题的程序的样子.

I am having trouble getting my program to respond to empty inputs. For example, say I wanted to prompt the user to enter a value for money with type BigDecimal as well as a currency type. Here is what the program in question looks like.

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);

    System.out.print("Enter the amount of money " 
                             + "and specify currency (USD or CNY): ");

    // initialize variable moneyInput
    BigDecimal moneyInput;

    // check if moneyInput is numeric
    try {
         moneyInput = input.nextBigDecimal();
    } catch (InputMismatchException e){
        System.err.println("InputMismatchException: non-numeric value");
        return;
    }

    // specify currency of moneyInput
    String currencyType = input.next();

    ...
}

因此,在这里,像100.00 USD这样的输入可以正常工作.

So here, an input like 100.00 USD, works fine.

Enter the amount of money and specify currency (USD or CNY): 100.00 USD
$100.00 USD ≈ ¥670.17 CNY

类似ASDF USD的输入会适当地导致错误消息.

An input like ASDF USD appropriately results in the error message.

Enter the amount of money and specify currency (USD or CNY): ASDF USD
InputMismatchException: non-numeric value

但是,如何强制程序响应空白输入,立即按下返回键或在第一行中输入一堆空格?例如:

But, how do I force the program to respond to blank inputs, either immediately pressing the return key or entering a bunch of spaces in the first line? For example:

Enter the amount of money and specify currency (USD or CNY): 





1000.00 USD
$1000.00 USD ≈ ¥6701.70 CNY

在上面的示例中,用户可以无限期地按下返回键,直到输入可读(有效或无效)的内容为止. 我想实现某种方式来检查用户是否在不输入任何有意义的内容的情况下按下了返回键.

In the above example, the user can just press the return key indefinitely until something readable (valid or invalid) is entered. I want to implement some way to check if the user pressed the return key without entering anything meaningful.

我不知道如何解释的另一个结果是,如果用户仅输入货币值,然后在最后输入货币之前多次按下[return](返回).

Another outcome that I don't know how to account for is if the user enters ONLY the monetary value, then presses [return] a bunch of times before finally inputting the currency.

示例:

Enter the amount of money and specify currency (USD or CNY): 100.00



USD
$100.00 USD ≈ ¥670.17 CNY

在输入数字值并按回车键后,如何使程序提示用户使用Please specify the currency:之类的内容?像

How do I get the program to prompt the user with something like Please specify the currency: after a numeric value is input and the user presses [return]? Something like

Enter the amount of money and specify currency (USD or CNY): 100.00
Please specify the currency: USD
$100.00 USD ≈ ¥670.17 CNY

我可以通过将try-catch块后的部分更改为以下内容来实现上述功能:

I was able to achieve the above functionality by changing the part after the try-catch block to:

input.nextLine();
System.out.print("Please specify the currency: ");
String currencyType = input.nextLine();

但是,使用此方法,程序将失去允许用户在一行中输入moneyInputcurrencyType的功能,就像第一个示例一样. (同样,仍然存在能够为每个提示无限期地按[返回]直到最终输入可读的问题.)

But using this method, the program loses the ability to allow the user to input both moneyInput and currencyType in one line, like in the first example. (And again, there is still the problem of being able to press [return] indefinitely for each of these prompts until something readable is finally input).

感谢阅读,对于冗长的帖子深表歉意.

Thanks for reading and sorry for the long post.

推荐答案

Scanner提供了两种基本的-有时是冲突的-用例:

Scanner offers two basic - and sometimes conflicting - use cases:

  1. 通过令牌读取输入内容,而忽略它们之间的任何空格(这是您的初始代码所做的事情)
  2. 通过 line 读取输入,而无需特别对待这些行的任何内容
  1. Read input by tokens, disregarding any whitespace inbetween (this is what your initial code does)
  2. Read input by line, without treating any contents of those lines specially

通常来说,将两者混为一谈是一个糟糕的主意(它可以起作用,但可能并非您的意图).像next()nextBigDecimal()这样的令牌读取方法会忽略换行符.

Generally speaking mixing the two is a poor idea (it works, but probably not how you intend). The token-reading methods like next() and nextBigDecimal() ignore newlines.

如果要处理 Enter ,则需要使用Scanner.nextLine()逐行读取用户的输入,并分别解析每行(即line.split("\\s+")),而不是使用Scanner的令牌读取方法.

If you want to handle Enter you need to read a user's input line-by-line with Scanner.nextLine() and parse each line individually (i.e. line.split("\\s+")), rather than use Scanner's token-reading methods.

有些人喜欢使用嵌套的Scanner并用一个Scanner逐行读取输入,然后将该行传递到新的Scanner中以对该行进行标记化.

Some people like to use nested Scanners and read input line by line with one Scanner then pass the line into a new Scanner to tokenize just that line.

例如:

try (Scanner in = new Scanner(System.in)) {
  while (in.hasNextLine()) {
    try {
      String line = in.nextLine();
      Scanner lineScan = new Scanner(line);
      BigDecimal moneyInput = lineScan.nextBigDecimal();
      String currency = lineScan.next();
      // do something
    } catch (NoSuchElementException | IllegalStateException e) {
      System.err.print("Please enter the VALUE followed by the CURRENCY");
    }
  }
}


如果您不想使用嵌套的Scanner,则还有许多其他的大致等效的机制.这是要点,但您可能想要添加其他错误处理代码(例如,如果new BigDecimal()引发异常:


If you don't want to use a nested Scanner there are a number of other roughly-equivalent mechanisms. Here's the gist, but you'll likely want to add additional error-handling code (e.g. if new BigDecimal() throws an exception:

使用String.split():

Using String.split():

String[] parts = line.split("\\s+");
if (parts.length == 2) {
  BigDecimal moneyInput = new BigDecimal(parts[0]);
  String currency = parts[1];
  // do something
} else {
  System.err.println("Please enter the VALUE followed by the CURRENCY");
}

使用Pattern:

Using Pattern:

/**
 * Matches one or more digits, optionally followed by a . and more digits,
 * followed by whitespace then one or more uppercase letters.
 */
private static final Pattern MONEY_PATTERN =
    Pattern.compile("(\\d+(?:\\.\\d+))\\s+([A-Z]+)");

然后:

Matcher m = MONEY_PATTERN.matcher(line);
if (m.matches()) {
  BigDecimal moneyInput = new BigDecimal(m.group(1));
  String currency = m.group(2);
// do something
} else {
  System.err.println("Please enter the VALUE followed by the CURRENCY");
}

这篇关于如何使Java扫描仪确认空白输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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