Clearing Scanner Buffer Java

Viewed 169

When working with nextInt() and nextLine() in java, do I need to clear the input buffer after using a series of nextInt() for instance

Scanner input = new Scanner(System.in);
int age = input.nextInt();
int height = input.nextInt();
int weight = input.nextInt();

in the above code, do I need to use input.nextLine() after every input.nextInt() to read the end of line character. Or does clearing the end of line character apply only when I am trying to read a string after an int for instance:

Scanner input = new Scanner(System.in);
int age = input.nextInt();
String name = input.nextLine();

in such a case where I'll have to use input.nextLine() after reading the age. I have tried using a input.nextLine() after reading integers and I am not seeing any difference in results. So what is the best practice?

1 Answers

99 out of a 100 tutorials and answers, including here on StackOverflow, say 'yes'. But they are incorrect. No, you don't.

But what is important is to ensure that your scanner is actually doing what you think it should, and therein lies the rub: Out of the box, Scanner is configured in a way that most people don't expect. Simply configure it properly and all is well.

Specifically, when you ask for keyboard input and you use a scanner to fetch it, most people I talk to seem to be under the impression that the enter key is what separates inputs. But that is not how scanner works by default. By default, any amount of whitespace separates inputs. This causes problems if you didn't want to split your inputs this way.

The fix is to tell scanner that single newline characters are the separator, instead of 'any amount of whitespace' (the thing that happens when you hit the enter key, is a newline character, same way the thing that happens when you hit the 'c' key is a 'c' character).

You do this with:

scanner.useDelimiter("\\R");

That's because \\R is regexp-ese for 'a newline' and scanner works by finding delimiters using a regex engine. This takes care of wonky definitions of 'newline' on various platforms (depending on a boatload of factors it's \n or \r\n, \\R takes care of all of this).

Then, make sure you understand scanner correctly. Essentially, that means: Do not ever call nextLine(), it does not do what you think it does. You said that the separator is newlines, thus, that input tokens are entire lines, so .next() gets you an entire line.

In other words:

  1. Call scanner.useDelimiter("\\R") immediately after creating it.
  2. String name = input.next();. nextLine has no purpose and just breaks things, don't call it.
  3. Failure to do these things does indeed make it look like interleaving nextLine() and nextInt() requires 'clearing buffers' and all that. Any attempt to fix this will break if the user ever decides to use that largest of keys on the keyboard: The space. Hence, don't try to 'fix the buffer'. Even though many tutorials do incorrectly suggest you can fix things that way.
Related