User Professor Hans Noodles
Professor Hans Noodles
Level 41

Scanner class

Published in the Java Developer group
Scanner class Hi! Our lesson today will be special! Previously, the process of completing tasks and writing programs was simple: we write some code, run the main() method, the program does what is required, and we're done. But now everything will change! Today we'll learn how to really interact with the program: we'll teach it how to respond to our actions! Before we start analyzing the code, have you ever had to deal with a device like a scanner? Probably. The insides of a scanner are quite complicated, but the basic idea of how it works is very simple: it reads data that the user provides (such as a passport or insurance policy) and stores this information in memory (for example, as an image). Today you're going to create your own scanner! Of course, it won't be able handle paper documents, but text will be no problem for it :) Let's go!

Java's Scanner class

Scanner class - 1First and foremost, we must get acquainted with the java.util.Scanner class. Its functionality is very simple. Like a real scanner, it reads data from a source that you specify. For example, a string, a file, the console. Next, it recognizes the information and processes it appropriately. Here's the simplest example:

public class Main {

   public static void main(String[] args) {

       Scanner scanner = new Scanner("It matters not how strait the gate,\n" +
               "How charged with punishments the scroll,\n" +
               "I am the master of my fate,\n" +
               "I am the captain of my soul");
       String s = scanner.nextLine();
       System.out.println(s);
   }
}
We've created a scanner object, and specified its data source (a string of text). The nextLine() method accesses the data source (our text with a quatrain), finds the next unread line (which is the first line in this case), and returns it. Then we display it on the console: Console output:

It matters not how strait the gate,
We can use the nextLine() method several times and display the entire poem excerpt:

public class Main {

   public static void main(String[] args) {

       Scanner scanner = new Scanner("It matters not how strait the gate,\n" +
               "How charged with punishments the scroll,\n" +
               "I am the master of my fate,\n" +
               "I am the captain of my soul");
       String s = scanner.nextLine();
       System.out.println(s);
       s = scanner.nextLine();
       System.out.println(s);
       s = scanner.nextLine();
       System.out.println(s);
       s = scanner.nextLine();
       System.out.println(s);
   }
}
Each time, our scanner takes one step forward and reads the next line. The program's output is displayed:

It matters not how strait the gate, 
How charged with punishments the scroll, 
I am the master of my fate, 
I am the captain of my soul
As we've already said, the scanner's data source doesn't have to be a string. For example, it could be the console. Some exciting news for you: previously, we just displayed data there, but now we'll read data from the keyboard! Let's see what else the Scanner class does:

public class Main {

   public static void main(String[] args) {

       Scanner sc = new Scanner(System.in);
       System.out.println("Enter a number:");

       int number = sc.nextInt();

       System.out.println("Thanks! You entered the number " + number);

   }
}
The nextInt() method reads and returns the entered number. In our program, we use it to assign a value to the variable number. It's already more like a real scanner! The program asks the user to enter any number. After the user has done this, the program thanks the user, displays the result, and finishes. But we still have a serious problem. The user might make a mistake and enter something wrong. Here is an example where our current program stops working:

public class Main {

   public static void main(String[] args) {

       Scanner sc = new Scanner(System.in);
       System.out.println("Enter a number:");

       int number = sc.nextInt();

       System.out.println("Thanks! You entered the number " + number);

   }
}
Let's try entering the string "CodeGym" instead a number: Console output:

Enter a number: 
CodeGym 
Exception in thread "main" java.util.InputMismatchException 
at java.util.Scanner.throwFor(Scanner.java:864) 
at java.util.Scanner.next(Scanner.java:1485) 
at java.util.Scanner.nextInt(Scanner.java:2117) 
at java.util.Scanner.nextInt(Scanner.java:2076) 
at Main.main(Main.java:10) Process finished with exit code 1
Uh, oh. We're in big trouble -_- To avoid such situations, we need to come up with a way to verify the data entered by the user. For example, if the user enters anything other than a number, it would be good to display a warning that the entered information is not a number. And if the information is okay, then we could confirmation. But this would require us to "look into the future" to see what's coming in our stream. Can Scanner do this? And how! And it has a slew of methods for doing this: hasNextInt() — This method checks whether the next chunk of input data is a number (returns true or false, as appropriate). hasNextLine() — This method checks whether the next chunk of input is a string. hasNextByte(), hasNextShort(), hasNextLong(), hasNextFloat(), hasNextDouble() — All these methods perform similar checks for the remaining data types. Let's try changing our number-reading program:

public class Main {

   public static void main(String[] args) {

       Scanner sc = new Scanner(System.in);
       System.out.println("Enter a number:");

       if (sc.hasNextInt()) {
           int number = sc.nextInt();
           System.out.println("Thanks! You entered the number " + number);
       } else {
           System.out.println("Sorry, but this is clearly not a number. Restart the program and try again!");
       }

   }
}
Now our program checks whether the next character entered is a number. And it displays confirmation only if it is. If the input doesn't pass the check, the program takes note and asks the user to try again. Basically, you can communicate with the Scanner object and find out in advance what data type awaits you. A number, string, or something else? A number? And what kind? An int, short, long?" This flexibility gives you the opportunity to build program logic that depends on the user's behavior. We should make note of another important method: useDelimiter(). You pass a string to this method. The string contains the characters you want to use as separators or delimiters. Scanner class - 2For example, suppose we suddenly became interested in Japanese poetry, and decided to use our scanner to read some haiku written by the great poet Matsuo Bashō. Even if three different verses are passed to us as one awkward string, we can easily split them and render them beautifully:

public class Main {
   public static void main(String[] args) {
       Scanner scan = new Scanner("On a withered branch'" +
               "A crow has alighted.'" +
               "Nightfall in autumn." +
               "''***''" +
               "Such a moon above,'" +
               "Like a tree cut at the root:'" +
               "he fresh cut is white." +
               "''***''" +
               "How the river floods!'" +
               "A heron wanders on short legs,'" +
               "Knee-deep in the water.");

       scan.useDelimiter("'");

       while (scan.hasNext()) {
           System.out.println(scan.next());
       }

       scan.close();
   }
}
We use "\n/*/*/*" (new line character and three asterisks) as our delimiter. As a result, we have beautiful console output, just like in books:
On a withered branch 
A crow has alighted. 
Nightfall in autumn. 

*** 

Such a moon above, 
Like a tree cut at the root: 
The fresh cut is white. 

*** 

How the river floods! 
A heron wanders on short legs, 
Knee-deep in the water.
This example has one more method that we must absolutely point out: close(). Like any object working with I/O streams, the scanner must be closed when it is done so it stops consuming the computer's resources. Never forget the close() method!

public class Main {

   public static void main(String[] args) {

       Scanner sc = new Scanner(System.in);
       System.out.println("Enter a number:");

       int number = sc.nextInt();

       System.out.println("Thanks! You entered the number " + number);
      
       sc.close(); // Now we've done everything right!

   }
}
That's it! As you can see, for how helpful it is, the Scanner class is quite easy to use! :)
Comments (57)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Jaime Padilla Level 7, Tempe, United States
9 April 2021
For those asking about the Delimiter, the article seems to reference the /n command and three asterisks but your delimiter is actually a single String quote '. Anytime the program seems a single quote it will split/space the group of words. Look at the single quote behind each sentence. When you get to the three asterisks you can see that there are four single quotes used to give greater separation between the poems. Maybe someone else can clarify the /n and three asterisks the article talks about, I'm still new.
Piotr Level 16
15 December 2020
there isn't anywhere explained why do I ever need to use scanners instead of just declaring String but hope I will find out at the right time
Chris J. Level 18, Arlington, United States
12 December 2020
scan.useDelimiter("\n/*/*/*") why are there forward slashes before the asterisks?
mastere Level 9, Rochester, United States
1 October 2020
The article should have had the Scanner class imported at the top of each code example like this: import java.util.Scanner; Doing this is important because if you try using the Scanner class without importing it first you will get an error like this: "Cannot find Scanner", or like this: "Cannot find symbol --> Scanner".
Lawson Level 29, Lagos, Nigeria
24 July 2020
i dont know abt others..but in my ide Scanner s=new Scanner("hello"); didnt work
Richi Level 15, Heilbronn, Deutschland
28 May 2020
Why this article dont say that I need "import java.util.Scanner;" at firts???
lyx3030 Level 10, Guangzhou, China
25 May 2020
scan.useDelimiter("\n/*/*/*") scan.useDelimiter("\n") scan.useDelimiter("\n/*") scan.useDelimiter("\n/*/*") have the same result. This example made me more confused.The asterisks is meaningless?
Dinesh Level 7, Delhi, India
6 May 2020
To understand useDelimiter() I tried to use "e" as delimiter in the given example of Japanese poetry but I didn`t got the output as I expected. I thought it will ommit all the e that is coming in the poem from every word that contains e letter in it. What is the dilemma with my "e" as a delimiter ?
Blaise Level 20, London, United Kingdom
3 May 2020

import java.util.Scanner;
Above should be the first line of each Scanner-example.
Blaise Level 20, London, United Kingdom
1 May 2020
Imagine delimiters as possible "slicing points". Any character or group of characters can be used as a slicing point. By default the delimiter is the new-line character, but we can change this by using the useDelimiter() method. Example:

Scanner scan = new Scanner("On a withered branch|A crow has alighted.|Nightfall in autumn.");  // one haiku as a single String
scan.useDelimiter("|");  // now you can "slice" the text at "|" to get one line of the haiku at a time
Real life example: CSV files (Comma-separated values): a common way to exchange data for databases and spreadsheets. CSV files are normal, human readable text files. You can read one line from the CSV file into a Scanner, then slice it at delimiters (usually commas) to get the values of "fields". See: https://en.wikipedia.org/wiki/Comma-separated_values