Why hasNextLine () never ends?

Sorry if this sounds too easy. I am very new to Java.

Here is the simple code I used to learn hasNextLine() . When I start it, I can not stop it. I thought that if you did not enter any input and hit Enter , you would have avoided the while .

Can someone explain to me how hasNextLine() works in this situation?

 import java.util.*; public class StringRaw { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNextLine()) { String str = sc.nextLine(); } System.out.print("YOU'VE GOT THROUGH"); } } 
+13
source share
5 answers

When you read System.in, you read from the keyboard by default, and this is an endless stream of input ... it has as many lines as the user needs to type. I think sending escape sequences for EOF might work, like CTL-Z (or is it CTL-D?).

Looking at my AOLII diagram of good code ... CTL-C is ETX and CTL-D is EOT; any of them should work to interrupt the text stream. CTL-Z is a SUB that should not work (but it can, because controls are historically interpreted very subjectively).

+15
source

Press Ctrl + D to complete the input from stdin. (Windows: Ctrl + Z ) or enter the input from the command:

 echo -e "abc\ndef" | java Program 
+5
source

CTRL-D is the end of a character or byte stream for UNIX / Linux, and CTRL-Z is the end of a character or byte stream for Windows (a historical artifact from the earliest days of Microsoft DOS).

With the question code, as written, an empty line will not exit the loop because hasNextLine () will not evaluate to false. It will have a line terminator in the input byte stream.

System.in is a stream of bytes from standard input, usually a console. Therefore, stopping the byte stream stops the loop. Although nextLine () does not block waiting for input, hasNextLine () does. The only way the code ends, in the form in which it was designed, is with CTRL-Z on Windows or CTRL-D on UNIX / Linux, which ends the stream of bytes, calls hasNextLine () so as not to block waiting for input and return a boolean false, which ends the while loop.

If you want it to end with an empty line input, you can check for non-empty lines as part of the loop continuation condition. The following code demonstrates how to change the basic design of a question that uses hasNextLine () and nextLine () for one that exits if it receives an empty string or the end of an input character (i.e. CTRL-Z on Windows or CTRL-D on UNIX / Linux). Additional code in the while condition uses the function of assignment operators, in which they can be evaluated as an expression to return the assigned value. Since this is a String object, the String.equals () method can be used with evaluation.

Another additional code simply adds some printed result to make what happens obvious.

 // HasNextLineEndDemo.java import java.util.*; public class HasNextLineEndDemo { public static void main(String[] args) { Scanner sc = new Scanner(System.in); // this code is a bit gee-whiz // the assignment expression gets assigned sc.nextLine() // only if there is one because of the && // if hasNextLine() is false, everything after the && // gets ignored // in addition, the assignment operator itself, if // executed, returns, just like a method return, // whatever was assigned to str which, // as a String object, can be tested to see if it is empty // using the String.equals() method int i = 1; // input line counter String str = " "; // have to seed this to other than "" System.out.printf("Input line %d: ", i); // prompt user while (sc.hasNextLine() && !(str = sc.nextLine()).equals("")) { System.out.printf("Line %d: ", i); System.out.println("'" + str + "'"); System.out.printf("Input line %d: ", ++i); } // end while System.out.println("\nYOU'VE GOT THROUGH"); } // end main } // end class HasNextLineEndDemo 
+5
source

As far as I understand, if you take an example of a result set object from JDBC or any iterator, then in these cases you will have a finite set of things, and iterators each time check whether the end of the set is reached. However, in the above case, they cannot find out the end of user input, i.e. hasNextLine () cannot find out when the user wants to shut down, and therefore it continues indefinitely. The best way is to put an additional condition in the for loop, which checks some condition inside the for loop, which will fail in the future. In the post above, @Jim's answer illustrates this.

In fact, using hasNextLine () as a loop limiter for console input is not recommended since it will never return false.

0
source

I had a similar problem with the socket input stream. Most of the solutions I found still block execution. Turns out there is a non-blocking check you can do with InputStream.available (). So in this case, the following should work:

 int x = System.in.available(); if (x!=0) { //Your code } 
0
source

All Articles