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

我无法让我的程序响应空输入。 例如,假设我想提示用户输入类型为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(); ... } 

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

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

ASDF USD这样的输入会适当地导致错误消息。

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

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

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

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

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

例:

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

如何让程序提示用户Please specify the currency:输入数值后用户按[返回]? 就像是

 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块之后的部分更改为:我能够实现上述function:

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

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

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

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

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

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

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

有些人喜欢使用嵌套的Scanner并逐行读取输入,然后将一行Scanner传递给新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"); } } } 

如果您不想使用嵌套的Scanner ,则还有许多其他大致相同的机制。 这是要点,但您可能希望添加其他error handling代码(例如,如果new BigDecimal()抛出exception:

使用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

 /** * 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+([AZ]+)"); 

然后:

 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"); }