How can I clear the Scanner buffer in Java?
Asked Answered
C

7

50

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();
Caridadcarie answered 15/5, 2012 at 15:36 Comment(2)
what do you mean with "Clear buffer"? clear console (like cls dos command)?Barong
I'm looking for something along the lines of: while(in.hasNext()) in.next();. For some reason that loop does not work.Caridadcarie
T
20

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.

Talbott answered 15/5, 2012 at 15:39 Comment(0)
R
53

Try this:

in.nextLine();

This advances the Scanner to the next line.

Revision answered 15/5, 2012 at 15:38 Comment(4)
Sometimes there are multiple lines entered, this only works for one line.Caridadcarie
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);Weald
@Weald 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 suggests you can get around this by creating a wrapper for System.in if you want to close it first.Lorislorita
@Lorislorita 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.Weald
T
20

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.

Talbott answered 15/5, 2012 at 15:39 Comment(0)
P
16

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!

Plerre answered 28/8, 2014 at 7:35 Comment(0)
I
9

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.");
Irascible answered 6/5, 2014 at 6:47 Comment(0)
L
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.

Lorislorita answered 7/5, 2019 at 23:2 Comment(1)
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.Checkrow
K
1
scan.nextLine();

Put the above line before reading String input

Knotting answered 11/5, 2021 at 9:4 Comment(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.Irmgardirmina
M
0

I am using this approach:

while (System.in.available() > 0) {
    scanner.nextLine();         
}
Mccaskill answered 25/4 at 13:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.