How to get Java scanner to acknowledge blank input?

£可爱£侵袭症+ 提交于 2019-12-01 05:46:57

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

  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

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 Scanners 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");
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!