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
Scanner
offers two basic - and sometimes conflicting - use cases:
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.
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.
Some people like to use nested Scanner
s and read input line by line with one Scanner
then pass the line into a new Scanner
to tokenize just that line.
For example:
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");
}
}
}
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:
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");
}
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]+)");
Then:
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");
}