0

I'm trying to write code that uses the Scanner class to get input from the user. But hasNext(), hasNextInt(), and hasNextLine() all run into infinite loops every time.

public static void getInput(ArrayList<Double> arr){

       Scanner input = new Scanner(System.in);
       String data = "";
       String init;
       while(input.hasNextLine()){
           init = input.nextLine();
           data += init;
       }
       .
       .
       .
   }
  • Well, how do **you** think it works? What should tell the scanner that there is no next line? Hint: pressing `ENTER` inputs a newline, which counts as... new line. Are you aware of `EOF` character? – Fureeish Jan 23 '18 at 23:21
  • 1
    you sure it is an 'infinite loop' or is it just `hasNextLine` blocking to wait for input? – Jochen Bedersdorfer Jan 23 '18 at 23:22
  • @Fureeish I understand that but shouldn't the next iteration consume the newline character? – Phoenix King Jan 23 '18 at 23:24
  • Of course it will consume it, but do you know what happens when the member of `hasNext...` family spots that you binded it with `System.in` and there is nothing in the Scanners buffer? It will wait for an input... and it will continue to do so untill you provide a character that will make `hasNext...` stop. For a `hasNextLine()` that would be an `end of file character`. For a `hasNextInt()` that would be any sequence of characters that cannot be converted to an `int`, and so on... – Fureeish Jan 23 '18 at 23:28
  • @Fureeish Oh i see. How do I provide the EOF character. Or do I create my own sentinel value? – Phoenix King Jan 23 '18 at 23:41

2 Answers2

2

Invoking hasNextLine() on a Scanner Object will return false if and only if the source is closed. This can occur by invoking close() on the InputStream, if an IOException occurs when the Scanner attempts to read bytes from the source or if the end of the stream has been reached (EOF). While an InputStream of a File will be closed when you reach the end and receive this marker, reading from System.in will block until data is available or an exception is thrown.

On Unix the EOF marker is usually provided by Ctrl-D while on Windows it is usually Ctrl-Z. If you are using an IDE you may find these to be different; For example the Intellij IDE on my Windows machine uses Ctrl-D and Eclipse has had problems in the past.

Zachary
  • 1,693
  • 1
  • 9
  • 13
  • 1
    "*when you create a `Scanner` with `System.in` it will wait for the next input until it has received an `EOF` marker.*" - this is **incorrect**. It will wait for a character that cannot be interpreted as the valid `hasNext[...]` part. `EOF` works for everything, but you don't have to use it every time. For example, `hasNextInt()` will return false as soon as there is a character that cannot be parsed to an `int`. – Fureeish Jan 24 '18 at 10:54
  • @Fureeish Good point. I meant to, and should have, said `hasNextLine()` will block until the next input or the `Scanner` infers the `InputStream` to be closed. – Zachary Jan 24 '18 at 12:04
1

I know this is old. For posterity's sake, I'm posting my experience too. I personally had an issue with scanner and hasNext() looping infinitely. I had called Scanner.close() earlier in the program, when my scanner was based on System.in for input. Remove the close on the scanner and instead instantiating new scanner fixed it for now. As a comment mentions, the scanner was blocked waiting for input so it just reads false always.

Links to the post that helped me:How can I clear the Scanner buffer in Java?

Dmonk
  • 31
  • 6