I've been racking my brain for a while trying to understand how Scanner works. So here's the code:
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
String p = sc.nextLine();
System.out.println(s);
System.out.println(p);
System.out.println(sc.hasNextLine());
What I expect:
Love is good <- press ENTER
Love is blind <- press ENTER
Love is good <- output
Love is blind <- output
false
What I have:
Love is good <- I press ENTER
Love is blind <- I press ENTER
Love is good <- output
Love is blind <- output
<- press ENTER
true <- output
What I do not understand:
What I have read: I have read a dozen of stackoverflow answers about using hasNextLine() after nextInt() and about how nextInt() does not consume the final symbol in the line but I don't understand why, even though I don't use nextInt() in here, I still need to press ENTER one more time and why hasNextLine() is true.
The second ENTER is needed because the program executes aaa = kb. nextLine() and you have to put in something. But I'm not sure where you really want the "Would you like to play again" question, the kb. nextLine() , and the test for "n" .
It is not possible to reopen System.in , System. out or System. err . The underlying native streams are file descriptors that are connected to other processes, or to files whose identity your application cannot discern.
The nextLine() method of the java. util. Scanner class scans from the current position until it finds a line separator delimiter. The method returns the String from the current position to the end of the line.
Instead of Scanner
use BufferedReader
like so:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Test {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String s = reader.readLine();
String p = reader.readLine();
System.out.println(s);
System.out.println(p);
System.out.println(reader.ready());
}
}
For more reading into the matter, look here and here. As a rule of thumb, when you need parsing stuff (like nextInt
) use Scanner
, otherwise stick to BufferedReader
. BufferedReader is a lot faster than Scanner
too.
Scanner
.The part that applies in your particular case is:
A scanning operation may block waiting for input.
What this means in your case is: after the first two lines are read by Scanner
, the Scanner
was waiting for input, caused by its method call sc.hasNextLine()
. Then when Enter was hit, it got an input (hence it prints true
, according to docs it returns true
when there is input). As after the method call sc.hasNextLine()
there are no more executable lines in your program, the program ends, giving the illusion that it required two enter hits.
From the Scanner documentation (emphasis by me):
public boolean hasNextLine()
Returns true if there is another line in the input of this scanner. This method may block while waiting for input. The scanner does not advance past any input.
What's probably happening is that hasNextLine
is blocking because it's waiting for input, which you give by pressing enter.
First of all you are using Scanner declared to System.in so this means you are asking .in to check if their is any more value so it waits for the user to input something and after you press enter it is obvious that it returns true.
So if you want to check s or p declare Scanner like this:
Scanner sc = new Scanner(s);
or
Scanner sc = new Scanner(p);
then check for sc.hasNextLine();
this should return false as much I know but for user input I would recommend to create another Scanner variable and then take values from the user and use sc for your hasNextline()
thing.
I hope the very first logic helps you.
You are asking for three lines of input!
Standard input always has one more line coming until you close the terminal. On a Unix system, you can probably press Ctrl+D at the end, and it will return flase
(= input closed).
The program would behave as expected if you had a finite input. But interactive input: how does the program know the user does not intend to input Shakespeare next?
The function hasNextLine()
will wait for new input to arrive (or for the signal that there cannot be new input). This function is not for "did the user already input another line" but instead means "wait for the next line". So for practical purposes, hasNextLine()
is equivalent to "is the user input still connected, and could it eventually contain another line".
Why do you need that last line? Just remove it!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With