[ACCEPTED]-Why does hasNextLine() never end?-java.util.scanner

Accepted answer
Score: 18

When reading from System.in, you are reading 11 from the keyboard, by default, and that 10 is an infinite input stream... it has as 9 many lines as the user cares to type. I 8 think sending the control sequence for EOF 7 might work, such as CTL-Z (or is it CTL-D?).

Looking 6 at my good-ol' ASCII chart... CTL-C is an 5 ETX and CTL-D is an EOT; either of those 4 should work to terminate a text stream. CTL-Z 3 is a SUB which should not work (but it might, since 2 controls are historically interpreted highly 1 subjectively).

Score: 8

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

With the question code 29 as written, an empty line won't exit the 28 loop because hasNextLine() won't evaluate 27 to false. It will have a line terminator 26 in the input byte stream.

System.in is a 25 byte stream from standard input, normally 24 the console. Ending the byte stream will 23 therefore stop the loop. Although nextLine() doesn't 22 block waiting for input, hasNextLine() does. The 21 only way the code terminates, as designed, is 20 with CTRL-Z in Windows or CTRL-D in UNIX/Linux, which 19 ends the byte stream, causes hasNextLine() not 18 to block waiting for input and to return 17 a boolean false which terminates the while 16 loop.

If you want it to terminate with an 15 empty line input you can check for non-empty 14 lines as part of the loop continuation condition. The 13 following code demonstrates how to change 12 the basic question design that uses hasNextLine() and 11 nextLine() to one that terminates if it 10 gets an empty line or an end of input character 9 (i.e. CTRL-Z in Windows or CTRL-D in UNIX/Linux). The 8 additional code in the while condition uses 7 a feature of assignment operators wherein 6 they can be evaluated like an expression 5 to return the value that was assigned. Since 4 it is a String object, the String.equals() method 3 can be used with the evaluation.

Other additional 2 code just adds some printed output to make 1 what is going on 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
Score: 6

Hit Ctrl + D to terminate input from stdin. (Windows: Ctrl + Z) or 1 provide input from a command:

echo -e "abc\ndef" | java Program
Score: 1

I had a similar problem with a socket input 5 stream. Most solutions I found would still 4 block the execution. It turns out there 3 is a not-blocking check you can do with 2 InputStream.available(). So in this case 1 the following should work:

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

As per my understanding , if you take an 16 example of result set object from JDBC or 15 any iterator then in these cases you have 14 a finite set of things and the iterators 13 each time check whether end of the set has 12 been reached. However in the above case 11 , their is no way of knowing the end of 10 user input i.e. hasNextLine() has no way 9 of knowing when user wants to terminate, and 8 hence it goes on infinitely. Best way is 7 to put additional condition on the for loop 6 that checks for some condition inside for 5 loop that fails in the future. In the above 4 post @Jim 's answer illustrates this.

In 3 fact using hasNextLine() as loop terminator 2 for console input should be discouraged 1 because it will never return false.

More Related questions