我无法让我的程序响应空输入。例如,假设我想提示用户输入类型为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
如何在输入数字值并且用户按下[return]后让程序提示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块之后的部分更改为:
,我能够实现上述功能input.nextLine();
System.out.print("Please specify the currency: ");
String currencyType = input.nextLine();
但是使用这种方法,程序失去了允许用户在一行中输入moneyInput
和currencyType
的能力,就像第一个例子中一样。 (同样,仍然存在能够无限期地按[返回]每个提示的问题,直到最终输入可读的内容为止。)
感谢您的阅读,并为长篇文章感到抱歉。
答案 0 :(得分:10)
Scanner
提供了两个基本的 - 有时是冲突的 - 用例:
一般来说,将两者混合是一个糟糕的想法(它有效,但可能不是你想要的)。像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
,则还有许多其他大致相同的机制。这是要点,但您可能希望添加其他错误处理代码(例如,如果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");
}
使用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");
}