new Scanner(System.in)
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;
āWell hello thereā
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 yes, use that
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;
nextBigDecimal
nextBigInteger
nextBoolean
nextByte
nextDouble
nextFloat
nextInt
nextLong
nextShort
next
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.
For example;
Ā Ā Ā Ā 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;
Hello
darkness
my
old
friend.
Iāve
come
to
see
you
yet
again.
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.
Peace out.
















