48

I have something like this:

    Scanner in=new Scanner(System.in);
    int rounds = 0;
    while (rounds < 1 || rounds > 3) {
        System.out.print("How many rounds? ");
        if (in.hasNextInt()) {
            rounds = in.nextInt();
        } else {
            System.out.println("Invalid input. Please try again.");
            System.out.println();
        }
        // Clear buffer
    }
    System.out.print(rounds+" rounds.");

How can I clear the buffer?

Edit: I tried the following, but it does not work for some reason:

while(in.hasNext())
    in.next();
Leo Jiang
  • 24,497
  • 49
  • 154
  • 284

6 Answers6

51

Try this:

in.nextLine();

This advances the Scanner to the next line.

Makoto
  • 104,088
  • 27
  • 192
  • 230
  • 4
    Sometimes there are multiple lines entered, this only works for one line. – Leo Jiang May 15 '12 at 20:39
  • 2
    You would think hasNextLine (or hasNext) could be used to check if more input is available, but this doesn't work in Java. The hasNextLine/hasNext methods always return true for the keyboard (System.in). The only way I've found to clear all buffered data without blocking is to open a new scanner: in.close(); in = new Scanner(System.in); – Georgie Jan 13 '18 at 23:12
  • 2
    @Georgie You would want to create the new Scanner without closing the old one. Closing the Scanner also closes the underlying readable (System.in in our case), so I get NoSuchElementExceptions on the next call to Scanner.next() if I close a System.in Scanner and create another one. If you really need to close the old one, [this StackOverflow answer](https://stackoverflow.com/questions/27286690/in-java-is-it-possible-to-re-open-system-in-after-closing-it) suggests you can get around this by creating a wrapper for System.in if you want to close it first. – SansWit May 07 '19 at 22:23
  • @SansWit Works for me on Java 8 update 211, Windows 7. Maybe the behaviour is different in different JVM implementations/Java versions, which would be bad. – Georgie May 14 '19 at 07:18
18

You can't explicitly clear Scanner's buffer. Internally, it may clear the buffer after a token is read, but that's an implementation detail outside of the porgrammers' reach.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
14

Use the following command:

in.nextLine();

right after

System.out.println("Invalid input. Please Try Again.");
System.out.println();

or after the following curly bracket (where your comment regarding it, is).

This command advances the scanner to the next line (when reading from a file or string, this simply reads the next line), thus essentially flushing it, in this case. It clears the buffer and readies the scanner for a new input. It can, preferably, be used for clearing the current buffer when a user has entered an invalid input (such as a letter when asked for a number).

Documentation of the method can be found here: http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#nextLine()

Hope this helps!

8

This should fix it...

Scanner in=new Scanner(System.in);
    int rounds = 0;
    while (rounds < 1 || rounds > 3) {
        System.out.print("How many rounds? ");
        if (in.hasNextInt()) {
            rounds = in.nextInt();
        } else {
            System.out.println("Invalid input. Please try again.");
            in.next(); // -->important
            System.out.println();
        }
        // Clear buffer
    }
    System.out.print(rounds+" rounds.");
rejun
  • 81
  • 1
  • 2
7

Other people have suggested using in.nextLine() to clear the buffer, which works for single-line input. As comments point out, however, sometimes System.in input can be multi-line.

You can instead create a new Scanner object where you want to clear the buffer if you are using System.in and not some other InputStream.

in = new Scanner(System.in);

If you do this, don't call in.close() first. Doing so will close System.in, and so you will get NoSuchElementExceptions on subsequent calls to in.nextInt(); System.in probably shouldn't be closed during your program.

(The above approach is specific to System.in. It might not be appropriate for other input streams.)

If you really need to close your Scanner object before creating a new one, this StackOverflow answer suggests creating an InputStream wrapper for System.in that has its own close() method that doesn't close the wrapped System.in stream. This is overkill for simple programs, though.

SansWit
  • 310
  • 3
  • 8
  • 3
    Creating a NEW Scanner object was best suggestion! But, make sure that there is NO REFERENCE to the OLD scanner object so that it can be **garbage collected**. – RafiAlhamd Nov 24 '19 at 06:03
1
scan.nextLine();

Put the above line before reading String input

Kamran Riyaz
  • 79
  • 2
  • 3
  • 1
    There's no `scan` variable in OP's code, the name of their scanner is `in`. Also this solution has already been suggested in several answers. – Eric Aya May 11 '21 at 09:33