Home > Blockchain >  Java Scanner.readLine consumes new line character, but when using println doesn't consume new l
Java Scanner.readLine consumes new line character, but when using println doesn't consume new l

Time:05-16

Code

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class MainT {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str="";
        List<String> strs = new ArrayList<>();
        for(int i= 0; i<3;i  ) {
            str = scanner.nextLine();
            strs.add(str);
        }
        System.out.println(strs);
    }
}

Console

1        // input
2        // input
[1, , 2]

I want to input three times. But only two time works. I thought scanner.nextLine consume new line character. But when i use System.out.println, it works three time.

Code

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class MainT {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str="";
        List<String> strs = new ArrayList<>();
        for(int i= 0; i<3;i  ) {
            str = scanner.nextLine();
            strs.add(str);
            System.out.println("String: "   str);
        }
        System.out.println(strs);
    }
}

Console

1         // input
String: 1         
2         // input
String: 2         
3         // input
String: 3         
[1, 2, 3] 

My environment is mac monterey 12.3.1 intel chip. I use adoptium temurin java 11. Why it works diffrent via using println?

CodePudding user response:

As the documentation of the nextLine() method states

Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. [...]

https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#nextLine()

Pressing the enter key corresponds to inputting two characters: a new line (\n) and a carriage return (\r). Both of these are line separators. When you type your first input and then press enter, the Scanner returns the first line, stops and then awaits for the second input (your second nextLine() invocation). However, since there is already a line terminator (the second line terminator left from the previous read), once you enter your second input, your scanner immediately halts at the beginning and returns an empty String. After that, the same thing keeps happening where only one read out of two seems to be taken.

What you need to do is to place an extra nextLine() between every read (not after every read) to get rid of that "extra" line terminator character.

Scanner scanner = new Scanner(System.in);
String str = "";
List<String> strs = new ArrayList<>();
System.out.println("Enter three numbers: ");
for (int i = 0; i < 3; i  ) {
    str = scanner.nextLine();
    // The last iteration does not need to get rid of that "extra" line terminator
    // because there is no following read; 
    // otherwise you would be forced to input an extra number
    if (i < 2) {
        scanner.nextLine();
    }
    strs.add(str);
}
System.out.println(strs);

Alternatively, you can ask for the input with a print message before every read. In this way, the Scanner's internal cursor will be moved forward the "extra" line separator due to the text written on screen and allowing you to retrieve the correct input with a single nextLine().

Scanner scanner = new Scanner(System.in);
String str = "";
List<String> strs = new ArrayList<>();
for (int i = 0; i < 3; i  ) {
    System.out.print("Enter a number: ");
    str = scanner.nextLine();
    strs.add(str);
}
System.out.println(strs);
  •  Tags:  
  • java
  • Related