Recently I was asked a simple question;
This may not be necessary at my level, but I'm asking for input of money and it breaks if the user enters a decimal
So, this is going to be hopefully a quick article about how to use the Scanner with regards to using it with the System.in input stream.
The Scanner class works by reading input from an input stream (System.in); it, by default, always reads input in as a String. This is a safe assumption on the part of the Scanner because there will be no mismatch problems with just reading into a String.
Scanner reads âtokensâ, as it calls them, based upon a delimiter, which is defaulted to whitespace characters. This means that if you input a line, such as;
Then it will process this as âWellâ, âhelloâ and âthereâ. As the Scanner reads from the input stream, when the line is input, it will buffer the input and read from it left to right. More on this bit later, under discussion of ânextLineâ.
When it is asked to read in a specific type (for example, `scanner.nextInt()`), internally it is doing the following;
If no, read input from the stream
If it does not, throw an InputMismatchException
This is a simple way of breaking down the logic, but the main important thing to understand is that the Scanner internally checks the input against a distinct pattern in order to determine if the input can be assigned / cast into the requested type.
So, as we are asking for an int, the pattern is going to determine; a) if the input is numerical, and b) the input does not have any decimal values. If the input fails these two checks, then the input does not match the expected value; this is an InputMismatchException which, if unhandled, will cause problems.
Ultimately, the Scanner has a number of preset patterns in order to make our lives easier;
There is no ânextStringâ because ânextâ returns a String.
So, as long as we know what the input that weâre expecting is, we can safely select which type we want from our scanner.
But, wait! One of the key aspects of programming applications is understanding that The User is an Idiot. No offense to any user, but if something can be made to go wrong, theyâll find it and just completely mess things up. We have to defensively program in order to help our users not mess everything up.
Luckily, Scanner has thought of that already and it has methods to help us determine things about the next input. These are the âhasâ methods.
When you call a one of Scannerâs âhasâ methods, it brings in the next input and keeps a hold of it, storing it internally. The âhasâ methods return a boolean; if the input can be assigned to the type requested, then it returns true. Otherwise, it returns false.
    if (scanner.hasNextDouble()) {
    System.out.println(â$â + scanner.nextDouble());
  } else {
    System.out.println(âThis was not a double: â + scanner.next());
  }
This allows us to create distinct conditionals and control the flow of applications, while also defensively programming against user input. We want to avoid throwing exceptions as much as possible at this point; instead we want to be programming around them.
The final important part of the Scanner is nextLine and tokens. As noted before, when the Scanner reads in from the terminal, it will buffer all âtokensâ in a list. So, with the input;
Hello darkness my old friend. Iâve come to see you yet again.
The token buffer then becomes;
Now, so when we call methods that check the input, it will read from that buffer instead of the terminal. So, you can call ânext()â 12 times before it will attempt to read from the terminal.
This can be seen with the following;
  Scanner scanner = new Scanner(System.in);
  while (scanner.hasNext()) {
    System.out.println(scanner.next());Â
  }
This will take an input, then for each token in that input, it will output the token, essentially splitting up your input into each individual âwordâ and repeating it on a different line.
To read in a whole line without worrying about whitespace, you can use scanner.nextLine()Â which will read in up to the New Line Character.Â
Hopefully, you have learned something about the Scanner class.