Scanner and I/O
User Interface
In BlueJ, you are able to interact directly with Classes and invoke their methods. However, a program in the real world runs without BlueJ, so it needs some interface for communication with the user. While many programs use a visual interface, it's simpler to use an all-text interface. We saw this previously when printing output, and we'll now see how to get the user's text input into the program with the Scanner class. This node will quickly cover the basics of Scanner, and you can refer to the official docs and the Learneroo Scanner reference for more information.
STDIN
The Scanner is used in Java to parse text input into useful pieces. Input can come from different sources, such as a text file. In this node, we will be getting input from the STDIN, or Standard Input. This is direct text input that comes into the program through the terminal. The terminal is where output is displayed when you type System.out.print
and it can also be used to get input with System.in
.
System.out.println("hello");
This will cause the terminal to pop up and display the output "hello". The terminal can also be used for typing in input, as will be shown below.
Question: What is System
?
Answer: It's a special Java class in the built-in java.lang
package that has a few useful methods. You cannot create instances of System
, but you can use its special fields System.in
and System.out
to access the Standard Input and Output.
Creating a Scanner
To use the Scanner, you need to import it, as seen in the last node. The Scanner has many different constructors, depending on what you want to scan in. To get input from the STDIN, you can create the following Scanner:
Scanner in = new Scanner(System.in);
next()
Now that you created the Scanner (and named it in
), you can use its methods to read from the Standard Input. Scanner includes a method called next()
for getting the next token of input. Tokens, by default, are space-separated text, which can also be called "words" in English. For example, if the program contains the following code:
String word1 = in.next();
...and the user types in
hello world
The Scanner will grab the first word typed ("hello") and assign it to word1
.
Scanner Methods
If you look at the methods of Scanner, you'll notice that many of them have similar names, like hasNextThing()
and nextThing()
. For example, there's hasNextInt() and nextInt(). The "hasNextThing" methods are used to check if the next token of text input is of type "Thing". For example, hasNextInt()
tells you if the next token of input can be interpreted as an integer. The "nextThing" methods take in the next token and converts it to type "Thing". For example, nextInt()
reads the next token and converts it to an int
to return. If the next token cannot be converted to an int
, nextInt()
will throw an error.
input | code | returns |
---|---|---|
42 | hasNextInt() |
true |
hello | hasNextInt() |
false |
42 | nextInt() |
42 (as an int) |
hello | nextInt() |
Error! (InputMismatchException) |
The hasNextThing methods are usually used together with the nextThing methods to make sure the next Token is the right type. For example, given a Scanner in
, you can use an if
statement to get number input:
if( in.hasNextInt() ){
int num = in.nextInt();
//...
}
Or a while statement, such as this one which scans in words of input:
ArrayList<String> words = new ArrayList<String>();
while( in.hasNext() ){
String word = in.next();
list.add(word);
}
The above code adds each token of input as a word to the ArrayList words
. It only gets the next input while
there still is input, so it won't cause an error by calling in.next()
when there's nothing left.
Learneroo
The challenges on this site usually involve doing something with raw text that is passed in on to the Standard Input. You usually do not need to process the text yourself, since its handled by the code that's included on the bottom. Instead, you can just fill in a method which takes in regular parameters. For example, this method asks you to "do Stuff" with two integer parameters:
public static int doStuff(int a, int b){ // two integer parameters, ready for action
//your code here
}
Q: How is the raw text converted into Java integers?
A: They are usually Java-fied with the Scanner class, which uses the appropriate methods to convert tokens of input into integers. It then passes the integers to doStuff
.
For example, this is the standard "boilerplate" code for processing a list of numbers with two numbers on each line:
Scanner in = new Scanner(System.in);
int n = in.nextInt(); for(int i=0; i < n; i++){ int a = in.nextInt(); int b = in.nextInt(); int result = doStuff(a, b); System.out.println(result); }
You can hover over each line of code above for some explanation. Since the test cases follow a specific format, the above code does not need to use while(in.hasNextInt() )
to check if there's still input.
Task
You've seen the basics of a Menu in Do-while loop, and Switch statement. Now see if you can use Scanner to create your own text-based menu for your Note program.
- In your Menu class, declare an instance variable
notebook
of Class Notebook and initialize it to a new Notebook in the constructor. - Create a method
runMenu()
and call it from the constructor. Then create a Scanner inrunMenu()
for processing the Standard Input.
import java.util.Scanner;
public class Menu
{
private Notebook notebook;
public Menu()
{
notebook = new Notebook();
runMenu();
}
public void runMenu()
{
Scanner in = new Scanner(System.in);
}
}
3. Declare a String input
for holding the tokens of input. Print a welcome message to the user when they run the Menu.
4. Create a do-while loop that displays a prompt message (such as "$ " or "Enter input: ") to the user as long as input
is not equal to "quit". Assign input
to the next word of input inside the loop (Use Scanner's next
method for this). If you run your code now, it should keep on displaying the prompt until you type in "quit".
public void runMenu()
{
Scanner in = new Scanner(System.in);
String input;
System.out.println("Welcome!. Please enter a command");
do {
System.out.print("Input $ ");
input = in.next();
} while(! input.equals("quit") );
}
5. Create a new method called menuChoice
which takes in a String parameter as input. Then create a new Scanner (for System.in
) inside menuChoice for getting the user's next word of input. Call menuChoice inside your runMenu
loop and pass it the first input.
6. Set up the Menu - Create a switch
case inside menuChoice
for different words the user enters. (On Java 6, you should use else-if statements instead.) Then invoke the appropriate methods from Notebook for each action. Use the Scanner where needed to process more input.
private void menuChoice(String input)
{
Scanner in = new Scanner(System.in); //new Scanner
String text;
int index;
switch (input){ //java 7 can handle Strings in switch
case "new":
System.out.println("Enter the text for your note");
text = in.nextLine();
Note note = new Note(text);
notebook.addNote(note);
System.out.println("Note created");
break;
case "print":
System.out.println("***all notes***");
notebook.printAllNotes();
break;
case "get":
System.out.println("Enter the index of the note you want");
if(in.hasNextInt()){
index = in.nextInt();
if(index < notebook.numNotes() ){
System.out.println( notebook.getNote(index).getContent() );
}
}
break;
case "search":
System.out.println("Enter the text to search");
text = in.nextLine();
index = notebook.search(text);
if(index >= 0){
System.out.println("Note found: " + index);
System.out.println(notebook.getNote(index));
}
else{
System.out.println("Text not found");
}
break;
case "delete":
System.out.println("enter number of note to delete");
if(in.hasNextInt()){
index = in.nextInt();
notebook.deleteNote(index);
System.out.println("Note deleted");
}
break;
case "help":
System.out.println("Enter a keyword for an action: \n" + "new: create new note. print: print all notes. get: get a note.\n" +
"delete: delete a note. search: search for a note." );
break;
case "quit":
//quits in loop
break;
default:
System.out.println("unknown command. Type 'help' for instructions or 'quit' to quit.");
break;
}
}
Challenge
You realized you want to scan in both words of input that the user types. Write a 2nd line of code that uses in
(your scanner) to assign the next word to the String variable word2
.
Please sign in or sign up to submit answers.
Alternatively, you can try out Learneroo before signing up.
Challenge
In one line of code, declare an integer variable a
and sets its value to the next integer of input. (Use your existing in
Scanner.)
Please sign in or sign up to submit answers.
Alternatively, you can try out Learneroo before signing up.
Comments
Lukas Dancak
Nov 13, 3:41 PMBlueJ do not want to compile "switch(input)" because input is String. What should I do ?
Learneroo
Nov 13, 3:43 PMIf you're using Java 6, you should use an if-else statement instead.
catypus
Jul 6, 10:56 AMIs it normal to initialize your Notebook in a menu class? Should I put it somewhere else? Would it be smart to create an Initialize class?
Learneroo
Jul 6, 9:39 PMIn this case I think it's fine. In a larger program it's true that it might make sense to create the Notebook separately.