Understanding Scanner's Nextline(), Next(), and Nextint() Methods

Understanding Scanner's nextLine(), next(), and nextInt() methods

nextLine() reads the remainder of the current line even if it is empty.

Correct.

nextInt() reads an integer but does not read the escape sequence "\n".

Correct1.

next() reads the current line but does not read the "\n".

Incorrect. In fact, the next() method reads the next complete token. That may or may not be the rest of the current line. And it may, or may not consume an end-of line, depending on where the end-of-line is. The precise behavior is described by the javadoc, and you probably need to read it carefully for yourself in order that you can fully understand the nuances.

So, in your example:

  1. The nextInt() call consumes the 2 character and leaves the position at the NL.

  2. The next() call skips the NL, consumes H and i, and leaves the cursor at the second NL.

  3. The nextLine() call consumes the rest of the 2nd line; i.e. the NL.


1 ... except that your terminology is wrong. When the data is being read, it is not an escape sequence. It is an end-of-line sequence that could consist of a CR, a NL or a CR NL depending on the platform. The escape sequences you are talking about are in Java source code, in string and character literals. They may >>represent<< a CR or NL or ... other characters.

What's the difference between next() and nextLine() methods from Scanner class?

I always prefer to read input using nextLine() and then parse the string.

Using next() will only return what comes before the delimiter (defaults to whitespace). nextLine() automatically moves the scanner down after returning the current line.

A useful tool for parsing data from nextLine() would be str.split("\\s+").

String data = scanner.nextLine();
String[] pieces = data.split("\\s+");
// Parse the pieces

For more information regarding the Scanner class or String class refer to the following links.

Scanner: http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html

String: http://docs.oracle.com/javase/7/docs/api/java/lang/String.html

Scanner is skipping nextLine() after using next() or nextFoo()?

That's because the Scanner.nextInt method does not read the newline character in your input created by hitting "Enter," and so the call to Scanner.nextLine returns after reading that newline.

You will encounter the similar behaviour when you use Scanner.nextLine after Scanner.next() or any Scanner.nextFoo method (except nextLine itself).

Workaround:

  • Either put a Scanner.nextLine call after each Scanner.nextInt or Scanner.nextFoo to consume rest of that line including newline

    int option = input.nextInt();
    input.nextLine(); // Consume newline left-over
    String str1 = input.nextLine();
  • Or, even better, read the input through Scanner.nextLine and convert your input to the proper format you need. For example, you may convert to an integer using Integer.parseInt(String) method.

    int option = 0;
    try {
    option = Integer.parseInt(input.nextLine());
    } catch (NumberFormatException e) {
    e.printStackTrace();
    }
    String str1 = input.nextLine();

Java Scanner next() reading range question

There is a little fault in your code

//scnr.nextLine(); this line is important to read \n before Chocolate Chips, If you wont use a dummy scnr.nextLine(); to read the new line then the new line will be read over here-

productName = scnr.nextLine();
System.out.println("2nd Name " + productName);

Here the productName will have the value \n and when it tries to read-

productPrice = scnr.nextInt();
System.out.println("2nd Price " + productPrice);

It expects to read an int but finds an String hence throws an exception.

Integer.parseInt(scanner.nextLine()) vs scanner.nextInt()

There are 2 observations :

  1. Using myScannerInstance.nextInt() leaves behind a new line character. So, if you call nextLine() after nextInt(), the nextLine() will read the new line character instead of the actual data. Consequently, you will have to add another nextLine() after the nextInt() to gobble up that dangling new-line character. nextLine() doesn't leave behind a new line character.

code :

int age=myScannerInstance.nextInt();
String name = myScannerInstance.nextLine();// here the actual name will not be read. The new line character will be read.

  1. nextInt() will again go back to the underlying stream and read. IO calls take time (expensive). It will do lot of checks to get the next integer. nextLine() will do those checks only once. So, if you call nextLine() once and read 5 integers (as a single line String), split them and parse them as integers (using Integer.parseInt()), it will be faster and more efficient than reading each int individually.

Using nextLine() + parseInt() will give you enormous performance benefit when you are running a very large loop.

Usage :

Using nextInt() gives you an additional advantage wherein you will get an exception if the input text is not an integer. example 123 is accepted.. 123sdsa will throw an InputMismatchException. So, you can catch it and handle it appropriately.

Using nextLine() will read the entire line, so, it will read the entire String sada1231 and then fail with NumberFormatException if it cannot parse the String as a number. You will have to handle that exception.

Generally, one nextLine() / nextInt() call won't make much of a difference. If you have a loop or if you are reading lot of data, then using readLine() with parseInt() will be very efficient.

Why multiple nextInt() works?

I have analyzed your question with debugging JRE Scanner class methods. When you called nextInt function, Scanner looks current buffer. If there is no available input, started listening to the keyboard until you press Enter key, whole keyboard characters appended to the buffer and tried to match that it is an integer or not. When it is found an integer nextInt returns the value and increments the buffer's position index. Next step, you called the nextInt again, and there is only \n character, then it is discarded and waited for the next integer pattern. Also, the buffer's next character is \n again. When you called nextLine it looks to the buffer and prints an empty line. So second nextLine is starting with empty text.

Maybe it can be confusing. Let's look at the scenario:

Note: Index ^ represents the buffer's reading position.



  1. Step
i1 = input.nextInt();
keyboard = 1 2 {Enter}
buffer = | 1 | 2 | \n |
index = ^

returns 12 and the next buffer position is located to \n




  1. Step
i2 = input.nextInt();
keyboard = 3 4 {Enter}
buffer = | 1 | 2 | \n | 3 | 4 | \n |
index = ^

returns 34 and the next buffer position is located to second \n




  1. Step
input.nextLine();

Buffer has \n character, so Scanner does not wait for keyboard and returns the value.

buffer = | 1 | 2 | \n | 3 | 4 | \n |
index = ^

returns empty text




  1. Step
s1 = input.nextLine();
keyboard = test {Enter}
buffer = | 1 | 2 | \n | 3 | 4 | \n | t | e | s | t | \n |
index = ^

returns test





Related Topics



Leave a reply



Submit