-1

Why don't I have to use nextLine when entering numbers into console on separate lines? I expected console to interpret end of each line having \n but program works the same whether I use nextLine() after each nextInt(). Using Eclipse.

// Example used
10 5      // # lines to read ,  divisor
22        //  if # divisible by divisor, count++ 
15 
10 
25 
17 
13 
15 
10 
7 
9 

public static void main(String[] args) {
    Scanner keyboard = new Scanner(System.in);
    int n = getNumber(keyboard);
    int k = getNumber(keyboard);
    int numLinesPassed = getNumberPassCriteria(keyboard, n, k);
    System.out.println("# Passed: " + numLinesPassed);
}
    
public static int getNumber(Scanner keyboard) {
    return keyboard.nextInt();
}
    
public static int getNumberPassCriteria(Scanner keyboard, int n, int k) {
    int counter = 0;

    for(int i = 0; i < n; i++) {
        int value = keyboard.nextInt();
        if (value % k == 0) {
            counter++;
        }
        //keyboard.nextLine();    not understand why I don't need this 
    }

    return counter;
}
Jayme
  • 745
  • 6
  • 19

2 Answers2

0

Because the default delimiter for Scanner is this pattern

\p{javaWhitespace}+

(Note: this exact pattern is not explicitly documented, but it's what you obtain calling the delimiter() method of Scanner when you instantiate one without explicitly specifying a different separator)

EDIT

As per user15244370's suggestion this mess of references I made is actually documented directly in the Scanner documentation here. You can skip directly to the list below.


The meaning of that pattern is documented in the documentation for the Pattern class which itself refers to the Character.isWhitespace method That pattern means a sequence of at least one of

  • a Unicode space character (SPACE_SEPARATOR, LINE_SEPARATOR, or PARAGRAPH_SEPARATOR) but is not also a non-breaking space ('\u00A0', '\u2007', '\u202F'). *'\t', U+0009 HORIZONTAL TABULATION.
  • '\n', U+000A LINE FEED.
  • '\u000B', U+000B VERTICAL TABULATION.
  • '\f', U+000C FORM FEED.
  • '\r', U+000D CARRIAGE RETURN.
  • '\u001C', U+001C FILE SEPARATOR.
  • '\u001D', U+001D GROUP SEPARATOR.
  • '\u001E', U+001E RECORD SEPARATOR.
  • '\u001F', U+001F UNIT SEPARATOR.

Which includes newline (the second bullet point).

Federico klez Culloca
  • 22,898
  • 15
  • 55
  • 90
  • 1
    documentation of delimiter has its own html anchor: [default-pattern](https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/Scanner.html#default-delimiter) And documentation of [`reset`](https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/Scanner.html#reset()) shows pattern (and a bit more) ((OK, it's a bit hidden)) –  Feb 28 '21 at 22:44
  • @user15244370 thanks, edited accordingly – Federico klez Culloca Feb 28 '21 at 22:52
  • I had the *pleasure* to search it some time ago... almost lost my faith in Javas documentation –  Feb 28 '21 at 22:54
0

Probably confused with Scanner is skipping nextLine() after using next() or nextFoo()?.

This is only a problem if you are reading, or trying to read the next line after the number using nextLine.

Why? nextInt reads a token, defined as text between delimiters (default white space including linefeed and carriage return), that means, if the input starts with one or more delimiter, these are ignored (discarded). nextLine does not read tokens, it just reads up to the newline; so if the next character is a newline, an empty string is returned.

Easy to test: just enter a couple of empty lines between the numbers - your code should read them without problems.