如何让Java扫描程序确认空白输入?

A i*_*ion 6 java input bigdecimal java.util.scanner

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

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();

    ...
}
Run Code Online (Sandbox Code Playgroud)

所以在这里,输入像100.00 USD,工作正常.

Enter the amount of money and specify currency (USD or CNY): 100.00 USD
$100.00 USD ? ?670.17 CNY
Run Code Online (Sandbox Code Playgroud)

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

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

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

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





1000.00 USD
$1000.00 USD ? ?6701.70 CNY
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,用户可以无限期地按下返回键,直到输入可读(有效或无效)的内容.我想实现一些方法来检查用户是否按下了返回键而没有输入任何有意义的内容.

我不知道如何解释的另一个结果是,如果用户仅输入货币值,则在最终输入货币之前按[返回]一堆.

例:

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



USD
$100.00 USD ? ?670.17 CNY
Run Code Online (Sandbox Code Playgroud)

如何让程序在Please specify the currency:输入数字值并且用户按[return]后提示用户输入?就像是

Enter the amount of money and specify currency (USD or CNY): 100.00
Please specify the currency: USD
$100.00 USD ? ?670.17 CNY
Run Code Online (Sandbox Code Playgroud)

通过将try-catch块之后的部分更改为:我能够实现上述功能:

input.nextLine();
System.out.print("Please specify the currency: ");
String currencyType = input.nextLine();
Run Code Online (Sandbox Code Playgroud)

但是,使用这种方法,程序丢失,以允许用户输入两者的能力moneyInputcurrencyType在同一行,如在第一个例子.(同样,仍然存在能够无限期地按[返回]每个这些提示的问题,直到最终输入可读的内容为止).

感谢阅读和抱歉长篇文章.

dim*_*414 11

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

  1. 通过令牌读取输入,忽略其间的任何空格(这是您的初始代码所做的)
  2. 逐行读取输入,而不特别处理这些行的任何内容

一般来说,混合两者是一个糟糕的想法(它的工作原理,但可能不是你想要的).令牌读取方法喜欢next()nextBigDecimal()忽略换行符.

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

有些人喜欢使用嵌套的Scanners并逐行读取输入,Scanner然后将该行传递给new Scanner来标记化该行.

例如:

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");
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

使用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");
}
Run Code Online (Sandbox Code Playgroud)

使用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]+)");
Run Code Online (Sandbox Code Playgroud)

然后:

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");
}
Run Code Online (Sandbox Code Playgroud)