Part V: Basic text-based user interaction with input/output using Scanner and System.out in Java

By | March 12, 2021

Introduction to the Java Scanner class

In Java you can interact with your users in various different ways, one of which is using the Scanner class that can be found in Java.

The Scanner class allows you to create a Scanner object which you then can use to collect user input to use in your program.

The Java Scanner is very easy to use and very useful for whenever you need your users to provide you with data for your program to process.

The Scanner object then in turn allows you to scan for multiple data types so that you are not limited to getting users to provide you with Strings exclusively, but also integers, doubles, etc.

Scanners can either read data from the:

  • System (System.in – in contrast to System.out that we use for printouts to the console)
  • or from a Source file
  • But can also use String variables as inputstreams

“Predicting” user inputted values using the Java Scanner class

Using the Scanner object, we can also “predict” or maybe more accurately get a “sneak-peak” of the value the user is entering, so before we collect and store the value, we anticipate it so that we can base our program logic around what kind of value is inputted by the user by “pausing” program execution between when your user enters the value, and we do something with it in our program.

This feature can be useful for both guiding program logic as well as determining how long to run collection of data – with the help of a while-loop we could define that data should be processed as long as there is another line inputted for example.

Giving us the opportunity to “intervene” if we deem it necessary, before the value inputted has already been saved/processed in our program.

Useful methods of the Scanner class in Java

Some of the most useful methods that I myself usually end up using from the Scanner class object is as follows:

Method Return
.hasNextDouble() Returns boolean true/false whether next Scanned value can be interpreted as a double data type or not
.hasNextInt() Returns boolean true/false based on if Scanned value can be interpreted as an integer data type or not
.hasNextLine() Returns boolean true/false based on if there is another line in the input of the Scanner or not
.next() Returns String (Finds and returns the next completed token (tokens usually separated by spaces – so e.g. one word))
.nextDouble() Returns double (Scans the next token of the user input as a double)
.nextInt() Returns integer (Scans the next token of the user input as an integer)
.nextLine() Returns String (Moves the Scanner past the current line and returns the input of the current line)

How to create a Scanner object to use for user input in Java

Scanner objects are easy to create and use, for this example we’re going to use System.in to read user input from the keyboard, but later in this article we will also demonstrate how you can create a Scanner that will read data from a Source file! But for the keyboard input via System.in, see below:

import java.util.Scanner;

Scanner scan = new Scanner(System.in);

Notice how we imported the Scanner class reference because we wanted to declare and initalize our Scanner with ease as we did above.

The alternative would be as we’ve covered in previous article that you need to specify the full path of the class when creating objects of the Scanner class.

Also note that we declare the “inputstream” for our Scanner to be System.in which corresponds to user input via keyboard (usually) in Java.

We also named our Scanner object “scan” to make it easy to remember and refer to in later use case examples we will cover.

We could here have entered either a Source File or a String variable as inputstream for our created Scanner object to read from as well.

Use cases with the Scanner object in Java programs

Get text from user with the Scanner object in Java

I usually only ever use the scan.nextLine() for this which returns an entire line of user input as a String. scan.next() could also be used for this, but note that the difference is that scan.next() only gets 1 token (tokens are usually separated by spaces, so for example it gets 1 word only, instead of the entire line of user input).

See example below:

Scanner scan = new Scanner(System.in);

String userInput = scan.nextLine(); // Once the program execution reaches this stage, program execution will stop and await user input, before continuing program execution
System.out.println(userInput); // Imagine user inputted the line "Hello World" for scan.nextLine(); then this line will print: "Hello World"

Since the scan.nextLine() method returns a String, we can choose to work with it immediately – or store it in a String variable for later processing and use.

Get integer values from user with the Scanner object in Java

This works similarily to how we did above with scan.nextLine(); See example below:

Scanner scan = new Scanner(System.in);

int number = scan.nextInt();

if(number > 5) 
{
   System.out.println(number); // If the user inputted integer value "number" that was scanned was bigger than 5, print the value stored in number integer variable
}

Get double values from user with the Scanner object in Java

Same as above, check out example below:

Scanner scan = new Scanner(System.in);

double decimalValue = scan.nextDouble();

System.out.println("Your inputted double value was: " + decimalValue); // If user inputted 3.0 thats what the output will read :)

“Anticipating” user input in program logic in Java

Using the .hasNextLine() and .hasNextInt() etc. methods in the Scanner class in Java, we can check a value scanned before storing or processing it in our program.

This can be useful to guide our program logic. But another possibility when using the Scanners .hasNextLine() or .hasNextInt(), etc. methods could be to run a while loop as long as there is input data to be processed. See below examples of use cases:

Scanner scan = new Scanner(System.in);

System.out.print("Enter an integer: ");
int userInput = 0;

if(scan.hasNextInt()) // If the user tries to enter a String, the program logic will evaluate this condition to false and the IF block will never be executed
{
   userInput = scan.nextInt();
   System.out.println("You entered the following integer: " + userInput);
}
// An example of reading numbers until no more numbers
Scanner scan = new Scanner(System.in);

System.out.println("Keep entering numbers until you're done: ");

while(scan.hasNextInt()) 
{
   System.out.println("Number entered: " + scan.nextInt());
}

// Above will print the following when user enters the numbers 15, 1, 2, 3, 4, 5 after each other and ends with the String "abc":
// Keep entering numbers until you're done: 
// 15
// Number entered: 15
// 1
// Number entered: 1
// 2
// Number entered: 2
// 3
// Number entered: 3
// 4
// Number entered: 4
// 5
// Number entered: 5
// abc <- here program will end since abc is not an integer and hence the while loop condition is no longer true :)
// Note: When abc was entered the user don't know what happens necessarily since nothing happens then the program just ends with no notification, one way to remedy that is to in the while loop add an IF for .hasNextInt() else <- where in the else you inform the user when program ends :)

The above example with the while loop is an extremely useful example of when you need to collect “x” unknown amounts of String values, integer values, double values or whatever from you users and store in an ArrayList or something which can dynamically expand, to fill it with values without having to specifically limit the program logic to a fixed amount. This is then a dynamic and useful alternative of doing it.

Print console messages for output and program updates with System.out in Java

By now you are probably very familiar with both the System.out.print(); and System.out.println(); methods, both of which can be very useful to relaying information to the user regarding program execution progress and status.

But I figured it could still be worth mentioning them here briefly just in case some of you still have some questions about them.

The difference between System.out.print(); and System.out.println(); is that System.out.print(); prints on the same row, so if you were to do 2x System.out.print(); calls after one another, the output would come after one another as well. Whilst when using System.out.println(); it prints 1x line of output at a time, making sure that two System.out.println(); never end up next to each other horizontally.

Both of these methods print output to the Console window in Java where the developer can see the output. Much similar to console.log(); in JavaScript.

The reason for mentioning these two methods here in this chapter is because they are responsible for a lot fo the user interaction in terms of output when coding in Java.

Both methods stem from the System class in Java, which by the way also can be used to trigger Garbage collection manually, Exit a program via exit(); method, as well as get the System time in milliseconds.

You can also use the class to specify alternate Input and Output streams (System.in and System.out). For example if you wish all of your program output to end up in log files that you have created, or if Scanners default input stream always should be from a file for example.

You can also access System properties via the System class in Java, etc. But you will be able to read more about the System class in Java later in our Appendix.

For now if you think it sounds interesting, you can read more about it from the Oracle Java documentation page here.

Using Scanner class to read from files in Java

This will be discussed in more detail in Part 8 of this website, but if you’re interested now and want to try it out on your own, by all means, feel free to check out the Oracle Java documentation for the Scanner class :)

Otherwise hang tight and we’ll get back to it in Part 8.

Use case: Text-based user-interface with menu using the Scanner class in Java

Here we will demonstrate a little more elaborate use case using the Scanner class in Java to build a basic text-based user-interface with a menu where users can interact with our program using said menu.

This is a really useful way of combining the Java Scanner class with program logic to shape how our users interact with a specific program, without having to use Graphical user interfaces.

This text-based user-interface menu could be used to build a calculator program where the user can enter menu alternatives via Strings or integers for example and then let their input guide which logic in the program should be executed.

This way you could basically create any kind of program you can think of where a menu might be useful to guide program logic :)

We are going to use a clever trick to keep the program alive until the user decides to “kill it” with our menu, using a while loop that keeps looping back the menu whenever the menu choice has executed its code so the user can keep interacting with our program for as long as they want and keep choosing multiple different menu alternatives one after the other.

See our demonstration of such a use case below (of a very basic calculator):

Scanner scan = new Scanner(System.in);

// We are going to use System.out.println() to present our menu and its choices and instructions of how to interact with the choices to our user
System.out.println("Welcome to our very basic calculator ;)\n" +
   "To use our calculator, simply input your choice of menu alternative and follow the instructions");

boolean running = true;

while(running) 
{
   System.out.println("(1) Addition\n"
      + "(2) Subtraction\n"
      + "(3) Multiplication\n"
      + "(4) Division\n"
      + "(-1) Exit"); 

   int choice = scan.nextInt();
   int a = 0; 
   int b = 0;

   switch(choice) 
   {
      case 1:
         System.out.println("Please input two integer values you wish to add: ");
         a = scan.nextInt();
         b = scan.nextInt();
         System.out.println("The sum of addition with your two inputted values: " + a + " and " + b + " = " + (a+b));
      break;

      case 2:
         System.out.println("Please input two integer values you wish to subtract: ");
         a = scan.nextInt(); 
         b = scan.nextInt();
         System.out.println("The difference of subtraction between your two inputted values: " + a + " and " + b + " = " + (a-b));
      break;

      case 3:
         System.out.println("Please input two integer values you wish to multiply: ");
         a = scan.nextInt();
         b = scan.nextInt();
         System.out.println("The product of multiplication between your two inputted values: " + a + " and " + b + " = " + (a*b));
      break;

      case 4:
         System.out.println("Please input two integer values you wish to divide (remainder will be lost): ");
         a = scan.nextInt();
         b = scan.nextInt();
         System.out.println("The quotient of division between your two inputted values: " + a + " and " + b + " = " + (a/b));
      break;

      case -1:
         System.out.println("Thank you for using our calculator program, please come again :)!"); // Let the user know that their exit sequence was accepted and program has now ended
         running = false; // Setting our boolean running variable to false here means after this Switch when the while condition is evaluated again, running will then be false and loop won't run again, ergo program loop exit
      break;
   }
}

Examples of Data validation in Java for when working with user input

Data validation is extremely important when coding programs that need to be able to deal with anything a user can throw at it.

As a practical example for this you can imagine a program with a login form where you’re asked to enter a username and password, very basic and standard stuff, but what happens if the input fields have no data validation and you decide to enter program logic into them? Now you might think this is an absurd idea, why would anyone enter program logic into a simple text field? Well it tend to happen :P Hackers might enjoy doing this just to take advantage of a beginner programmers naïvité for example. If then the input fields don’t deal with these scenarios, and your form fields are connected to a database where its supposed to compare inputted username and password with what exist in the database table, then you might end up being SQL injected for example.

Your program needs to be able to anticipate what the user might do – as well as what they shouldn’t do, in order for it to have appropriate logic that can deal with whatever the user decides to do in your program – whoever they may be.

So for another example, say you have a program where you expect the user to input an integer value, that you then later will do some calculations with… What happens when the user enters a String value instead? Maybe they misunderstood your program at some point and thought it would be a String to be entered at that specific moment instead of an integer, or something else, it doesn’t really matter why the user did something unexpected at this point – well it can matter in that understanding of the why, might help you better design a program where the chance of it happening is minimal. But it still means that even if the design is perfect and the chance of anyone misunderstanding anything is very low, the fact is that there is still a chance that the user could choose to go another way than what you intended for them to in your program. And when this happens, your program needs to be able to deal with this reality, if not, your program might end up crashing causing horrific user experiences and in worst case imprinting such a bad experience that not only does the user think you have done a terrible job designing the program, but the program and its possible useful functionality in and of itself, might not be used by people because of how un-user-friendly the program is designed. It might also result in being a vulnerability which can be costly for you as a developere as well as the customer who asked you to design the program in the first place.

So how do we deal with all of this then? It’s simple, start coding contingencies for whichever scenario you know or think could have a chance of happening.

This is why so many programs – by the way in the real world often have to do “bug-fixes” – because a bug is unexpected behaviour that had not been accounted for by the programmer, maybe because of unexpected user behaviour, or because of bad coding, either way, it’s impossible to find all bugs for programs, because sooner or later, a user might surprise you and use your program in some way completely different than how you intended for it to be used and then the program is not ready for that use case and have bad or flawed user experience because of it.

Since its extremely difficult to anticipate every single possible outcome for how users might use a program (some might abuse every inch of it just because they can and to test its limits – not regular users usually though, but for example hackers), all you can do is your best to anticipate as much as possible and code logic to deal with those possible outcomes.

It also helps to have a good understanding of what you are coding and how you are coding it, so that anyone who intends to limit-test your program logic to its edges, will have a difficult time to abuse your program. Because as mentioned above, it might not just be regular users who surprise you, but one of those users might also end up being a hacker with their only intention to break your program to find possible flaws and limits (its like a puzzle in a way).

Regular Expressions are usually very helpful for data validation since they can be used to detect patterns in Strings for example, and help you craft logic to deal with those patterns.

For some simpler examples of data validation, see below:

// In this example, we want the user to input an integer between the values 0-100
Scanner scan = new Scanner(System.in);

System.out.println("Enter an integer value between 0-100: "); // Give instructions to the user of what they should do in the program

if(scan.hasNextInt()) // First we want to make sure that the input is an actual integer and nothing else
{
   int userInput = -1;
   boolean correctInput = false; // We are going to use this boolean correctData variable to determine the running of a while-loop to collect data as long as it's incorrect
   
   while(!correctInput) // Notice the unary ! negator operator that says "run while-loop as long as correctInput is NOT true - ergo false, reverse logic can sometimes be useful to easier understand our programs logic flow)
   {
      userInput = scan.nextInt();
      if(userInput >= 0 && userInput <= 100) {
         correctInput = true; // If the collected user input integer was higher than or equal to 0 and less than or equal to 100 (between 0-100 as we wanted) then we end the loop by setting our boolean correctData variable to true, but only then, if this IF condition is not true, keep running the data collection loop
      }else {
         System.out.println("You failed to enter an appropriate integer of value between 0-100, please try again..."); // Inform the user of what went wrong and whats expected of them next
      }
   }

   if(userInput > 0) // If correctData was set to true meaning we got the data we wanted - an integer value between and including 0-100 we can do something with it here
   {
      System.out.println("Your entered integer value between 0-100 was: " + userInput); // Here the user completed our program, so we print what value they inputted as final user feedback/output of our program 
   }
}

Leave a Reply

Your email address will not be published. Required fields are marked *