---
title: "how it works: java scanner"
tags: programming, tutorial
---
# the nextLine scanner problem
you're trying to write a program that asks the user to type a number using `nextInt()`. then you ask them to type some text with `nextLine()`, but... it just fails! it doesn't even give you an error message; it completely skips your `nextLine()` function :cry:
this is the most common issue to run into when starting out with scanners. even if you've been lucky not to run into it, understanding *why* it happens gets at the core of understanding scanners. so let's figure it out :slightly_smiling_face:
## setting it up
setting up a scanner is pretty simple
```java
Scanner keyboard = new Scanner(System.in);
```
after this, you can ask the user a question like so
```java
System.out.print("Enter your name: ");
String name = keyboard.nextLine();
```
## the problem
but something *weird* happens when you try to use `nextInt()`, `nextFloat()`, or any of the other `next___()` scanner functions followed by `nextLine()`
```java
System.out.print("Enter your age: ");
int age = keyboard.nextInt();
System.out.print("Enter your name: ");
String name = keyboard.nextLine();
```

it's as if java just skips right over the `keyboard.nextLine()` function and sets the `name` variable to an empty string! and that's almost exactly what's happening behind the scenes
## the scanner buffer
whenever you use one of a scanner's `next___()` functions, two things happen:
1. it stores *everything* you typed into a buffer
2. it'll look for the next int, float, word, etc based on which function you used
but what's important to know is that, after it finds and returns a match, it *doesn't* delete the rest of its buffer! that means if you use `nextInt()` and the user types `23 apples`, the `23` will be returned and the string `" apples"` will be sitting in the buffer waiting for the next function you use.
### newlines
the other important thing to know is how scanners handle *newlines*. this is a special character that represents breaks between lines of text. it's how you separate paragraphs. in the coding world, it's represented as a `\n`. if i have a document that reads
```
hello
world
```
this would be represented in code as `"hello\nworld"`. and one of these newline characters gets sent to the scanner buffer each time you hit `enter`. looking for that `\n` is how the `nextLine()` function knows that it's found the end of a line
### the cursor
you can think of the buffer this way: the scanner has a *cursor* (like your cursor when editing a document) that it moves through the buffer to keep track of where it's at.
going back to our *23 apples* example, our buffer looks like this after the user hits enter: `23 apples\n`. when you call `nextInt()`, picture the scanner moving a cursor through the buffer like so:
`|23 apples\n`
`2|3 apples\n`
`23| apples\n`
bam, right there it says "whoops, no more numbers" and stops. it returns the `23` and leaves ` apples\n` in the buffer. then when you call `nextLine()` it does the same thing, except instead of stopping at a space it'll stop at the `\n`
### drop the newline
the last thing to understand, before explaining the mechanism behind our problem and how to solve it, is that `nextLine()` does something slightly different from all of the other `next___()` functions. in the last example, we saw how `nextInt()` stops the cursor before it reaches the space, leaving ` apples` (with a space) in the buffer. it keeps moving the cursor until there are no more numbers and then stops. `nextLine()` keeps moving the cursor until it finds a `\n` character and then moves the cursor *just past* it.
that is, if we have `hello\nworld` in the buffer, calling `nextLine()` will move the cursor:
`|hello\nworld`
`h|ello\nworld`
`he|llo\nworld`
`hel|lo\nworld`
`hell|o\nworld`
`hello|\nworld`
`hello\n|world`
but wait, does that mean that if we run `String word = keyboard.nextLine()` that `word` will be set to `"hello\n"`? nope! `nextLine()` takes care of that by dropping the `\n` character from its output. *that's* what makes it different from other scanner functions and why it'll be the solution to our issue.
## putting it together
so let's write a program that asks the user for their age, name, and favorite color
```java
System.out.print("Age: ");
int age = keyboard.nextInt();
System.out.print("Name: ");
String name = keyboard.nextLine();
System.out.print("Favorite color: ");
String color = keyboard.nextLine();
```
the user might type something like this
```
23
jack
purple
```
or in code format: `23\njack\npurple\n`. so let's look at what happens at each `next___()` function (with a `|` to represent where the cursor is *after* the function finishes):
| function | cursor | returns |
| ------------ | ---------------------- | -------- |
| `nextInt()` | `23\|\njack\npurple\n` | `23` |
| `nextLine()` | `23\n\|jack\npurple\n` | `""` |
| `nextLine()` | `23\njack\n\|purple\n` | `"jack"` |
see what happened there? the first time we call `nextLine()` trying to get the user's `name`, the buffer in front of the cursor looks like `\njack\npurple\n`. so `nextLine()` does what it usually does and stops as soon as it finds the first `\n` (which is there from when the user typed `23` and hit enter). it stopped before we ever even got to the name! which means the second time we called `nextLine()`, trying to get the user's favorite color, the cursor was way further back than we expected, and we got the user's name instead.
to re-iterate:
1. the user typed `23\n`
2. `nextInt()` grabbed the number `23` but left the `\n` in the buffer
3. so when we called `nextLine()`, it just stopped at the `\n` leftover from the `23`, rather than getting the name that the user typed after it
## the solution
you might already know this or have been able to infer it from everything we've discussed, but the solution is pretty simple: any time we expect the user to hit enter after a number, we need to call `nextLine()` after calling `nextInt()`. when the user types a number and hits `enter`, it leaves a `\n` in our buffer that `nextInt()` doesn't remove, so we need to call `nextLine()` to remove it. this same idea applies to `nextFloat()`, `nextChar()`, etc. for our example, this looks like:
```java
System.out.print("Age: ");
int age = keyboard.nextInt();
// move past the extra newline from hitting enter
keyboard.nextLine();
System.out.print("Name: ");
String name = keyboard.nextLine();
System.out.print("Favorite color: ");
String color = keyboard.nextLine();
```
and there we go! we don't even need to store the output in a variable; we just call `nextLine()` to move the cursor and move on.
### when to use it
after learning this, some people are tempted to *always* put an extra `nextLine()` after any `nextInt()`, `nextFloat()`, etc, but we only want to use it specifically when we expect the user to hit the `enter` key after an integer.
for example, suppose we want to ask the user for their 2 favorite numbers and then their name
```java
System.out.println("What are you 2 favorite numbers?");
int num1 = keyboard.nextInt();
int num2 = keyboard.nextInt();
// move past the extra newline from hitting enter
keyboard.nextLine();
System.out.println("What is your name?");
String name = keyboard.nextLine();
```
we don't want to call `nextLine()` after *every* time we use `nextInt()`. we only want to use it when we know the user hit the enter key after a *specific* int (`num2` in our example)
## 23 apples and a space
you might have noticed in the `23 apples` example that, after calling `nextInt()`, we're left with ` apples\n` in the buffer---with a space in the beginning. so if we then use `nextLine()`, the output will be `" apples"`! we figured out how to move the cursor past a *newline*, but it's not a newline we want to skip past this time, and there's no `nextSpace()` function to move our cursor past that space.
instead, we can use `skip()`. we can pass a string to skip, and it'll move the cursor past that text in the buffer.
so our new code could become
```java
System.out.println("Enter a quantity and type of items:");
int quantity = keyboard.nextInt();
keyboard.skip(" ");
String itemType = keyboard.nextLine();
```
if the user types `23 apples\n`, then:
* `nextInt()` will return `23`
* `skip(" ")` will move the cursor past the space
* `nextLine()` will return just the word `"apples"` with no space
### beware
if you use `skip()`, but the string you specify isn't the *immediately next* string in the scanner buffer, it'll just hang indefinitely! it's not like any of the other scanner functions; it won't just look until it finds the thing it's looking for and then stop there.
e.g. if the user had typed `23apples\n` without a space, `keyboard.nextInt()` would have moved the cursor to `23|apples\n` and then `keyboard.skip(" ")` would have just frozen our program because the very next character is an "a" and not a space.
if you're not sure what the user is going to type, then use `next()` or `nextLine()` like normal and simply remove the space afterwards
```java
String itemType = keyboard.nextLine(); // " apples"
itemType = itemType.strip(); // "apples"
```
## summary
* whenever you hit enter, you add that line of text to the scanner buffer with a `\n` at the end
* `nextLine()` moves the buffer cursor *past* the next `\n` character it finds and removes that `\n` from its output
* `next()` does the same thing, except it'll look for the next space, tab, or newline
* `nextInt()`, `nextFloat()`, and every other `next___()` function moves the cursor just *after* the next int, float, etc it finds and *doesn't* remove anything from the buffer or its output.
## fin
and that's it! hopefully now you have a better grasp on how scanners work :slightly_smiling_face: