Java: Try to Understand Getting Inputs from Users Using Scanner - java

I have this programs and a few questions regarding to how .next(), .nextInt(), .hasNext() and .hasNextInt() of Scanner class work. Thank you in advance for any of your help :)
import java.util.Scanner;
public class test {
public static void main (String[] args) {
Scanner console = new Scanner(System.in);
int age;
System.out.print("Please enter your age: ");
while (!console.hasNextInt()) {
System.out.print("Please re-enter your age: ");
console.next();
}
age = console.nextInt();
System.out.println("Your age is "+age);
}
}
1/ When !console.hasNextInt() is executed for the first time, why does it ask for an input?
I thought at first the console is empty, so !console.hasNextInt() is True (empty is not an int), then it should go directly from "Please enter your age: " to "Please re-enter your age: " but my thought seems to be wrong.
Here, the user needs to enter something before "Please re-enter your age: " is printed.
2/ The data type of console.next() is always a String (I tried making int s = console.next(); and it gave an error), then why isn't this a infinite loop?
3/ For an instance, when it comes to console.next();, I input 21. Why does age have the value of 21? I thought because of console.hasNextInt(), I need to enter another number, and that new number will be the value of age.

The java.util.Scanner.hasNextInt() method returns true if the next
token in this scanner's input can be interpreted as an int value in
the default radix using the nextInt() method.
When you start with a non integer input, hasNextInt() will be false and you will enter while loop. Then it will prompt you to re-enter your age. But if you start with integer, you won't enter the loop. Your age will be printed.
console.next() means it takes next input token and returns String. If you write down your code as:
String s = null;
while (!console.hasNextInt()) {
s = console.next();
System.out.println("You entered an invalid input: " + s);
System.out.print("Please re-enter your age: ");
}
console.next() is being used for handling the non-integer inputs. Now, if you enter a non-integer input twenty, you'll see that console.hasNextInt() will be false and console.next() will read it.

hasNextInt() waits for an input string and then tells you if can be converted to an int. With that in mind, let's go over your questions:
When !console.hasNextInt() is executed for the first time, why does it ask for an input?
Because it blocks until there's some input from the console.
The data type of console.next() is always a String (I tried making int s = console.next(); and it gave an error), then why isn't this a infinite loop?
Because hasNextInt() returns true when the input can be converted to an int, for example "21".
For an instance, when it comes to console.next();, I input 21. Why does age have the value of 21? I thought because of console.hasNextInt(), I need to enter another number, and that new number will be the value of age.
Calling next() doesn't wait for a new input, it just swallows the input that was tested by hasNextInt() so the scanner can move on to the next one. It could have been the first statement in the loop, with the same effect.

Related

Force user to enter a valid number using the Java scanner

I have a simple code that asks for the age of a user. Everything is working as it should, except, if I type nothing and simply press enter I enter into something - maybe infinite loop? I am not sure but I cannot get out of it.
I have seen countless questions and responses for this topic when dealing with strings but barely any with byte (or int).
This is my code:
//App #2: Age
System.out.print("Enter your Age: ");
byte age = scanner.nextByte();
while (!scanner.hasNext()) {
System.out.println("Please enter a valid number.");
byte test = scanner.nextByte();
}
if (age > 16) {
applicant.age = age;
System.out.println(age);
}
else
System.out.println("You must be at least 17 years old to obtain a microloan.");
What can I do to force a user to enter a valid number?
Your loop needs to continue as long as additional input is available (i.e., scanner.hasNext()) but it isn't a valid byte (i.e., !scanner.hashNextByte()). You should also remember to consume (next()) any invalid string so the next inputed string can be evaluated:
while (scanner.hasNext() && !scanner.hasNextByte()) {
System.out.println("Please enter a valid number.");
scanner.next(); // Discard the invalid string
}
// Now we have a valid byte, read it:
byte age = scanner.nextByte();

Java scanner expecting more inputs than needed

Im having some trouble with scanning user input in one of my first java programs. When I compile and run this, I am immediately prompted for input (i.e the command line stops and blinks). When I enter anything, the first line is printed, asking me to enter an integer. Then the second line is printed and I'm prompted to enter another value.
The output from this program is the first two values that I input. This is hard to explain, but it basically asks for 3 input values and only uses two.
import java.util.Scanner;
public class objects
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.println("Enter an integer please...");
int input = sc.nextInt();
System.out.println("Enter your name please...");
String name = sc.nextLine();
System.out.println("The read values: " + input + ", " + name);
sc.close();
}
}
Put a System.out.flush() command after your println statements if you're reading from the console directly afterward
just use this:
Scanner sc = new Scanner(System.in);
System.out.print ("Enter your name please... ");
String name = sc.nextLine();
System.out.print ("Enter an integer please... ");
int input = sc.nextInt();
System.out.println ("The read values: " + input + ", " + name);
i just moved the integer below the name and it sorta fixed it. hahaha
When you introduce a number you press enter key, nextInt() uses the number but the enter (\n) remains buffered. After this if you call again nextInt(), Java tries to convert \n into a number giving you a NumberFormatException, but if you invoke nextLine() they read the enter as empty string
Here you have a better explanation and one solution
Can't use Scanner.nextInt() and Scanner.nextLine() together
It seems this is an error to do with my installation of VirtualBox. No matter what I try, the problem persists. Even if i try to only read ONE integer, it will ask me to input two values.
Thanks for everyone who tried to help, I learned a lot just trying to debug this.

How to check for user input without exiting for error

I need to check the user input and ask for a correct one if the value is not a digit. However when I do this code, the program displays an error message and then crashes- it does not ask the user to give a new input. How can that be fixed? Thank you!
import java.util.Scanner;
import java.lang.Math;
public class CentimeterInch
{
public static void main (String [] args)
{
final int MAX=100, feet=12, meter=100;
final double inch=2.54;
Scanner scan = new Scanner (System.in);
System.out.println ("This program converts distances. ");
System.out.println ("Enter distance and unit (e.g. 37 1 or 100 2):");
double distance=scan.nextDouble();
if (!scan.hasNextDouble())
{
System.out.println ("please enter a numeric value");
distance=scan.nextDouble();
}
int unitType = scan.nextInt();
if (distance<0)
{
System.out.println ("Please enter a non negative distance");
}
....
Just bring the if clause before performing scan.nextDouble().
if (!scan.hasNextDouble())
{
System.out.println ("please enter a numeric value");
scan.nextLine();
distance=scan.nextDouble();
}
double distance=scan.nextDouble();
First make sure that the number to be read is a double value, then read it. You were doing the reverse
What is scan.nextLine() doing here?
Suppose the user enters abc 2. scan.hasNextDouble() checks wether the token to be read next is a double value or not. It's not, so scan.hasNextDouble() evaluates to false and the if clause gets executed. Inside the if clause, you have scan.nextLine(). It simply discards the current input from scan, thus flushing scan. If you don't do so, then scan still contains abc 2 and upon executing distance = scan.nextDouble(), the compiler issues an error.
It's better if you replace if with while. Suppose user gives wrong input. Your program checks the input and finds out that it's not a double value. The if clause if executed and the user is asked to enter a numeric value. What if the user again enters a wrong input. This time, you will get an error. Using a while loop makes your program to keep asking the user for a correct input until he enters a numeric value.

Getting java.util.InputMismatch upon typing "exit"

Scanner input = new Scanner (System.in);
System.out.println("Enter -1 to exit the program");
System.out.println("Enter the search key: ");
int searchkey = input.nextInt();
String exit = input.nextLine();
while (!exit.equals("exit"))
{
linear(array, searchkey);
binary(array,searchkey);
System.out.println();
System.out.println("Enter exit to end the program");
System.out.println("Enter the search key: ");
searchkey = input.nextInt();
exit = input.nextLine();
}
I am getting an InputMismatch exception. I know this is because of searchkey. How can I use the string to exit the program?
If "exit" is the first thing you type when you run the program then you will crash. This is because the first read in of the input is input.nextInt(). If you type "exit" and input expects an int, it will throw the InputMismatch exception.
To correct for this, you can use input.next() if you dont know what you are going to get. Then you can do your own parsing on the input.
You are calling nextInt without checking it is an int. You need to check hasNextInt() first because they might have typed "exit" as you instructed.
My guess is you type "exit" immediately after the print statement, so it gets captured by
searchkey= input.nextInt();
If nextInt()gets a non-int passed to it, it will cause an exception.
input.nextInt() expects you to enter an integer (like -1, 0, 1, 2..) If you introduce "exit" then it will throw that exception.
Maybe if you change the position of your prompt and your instructions?
System.out.println("Enter -1 to exit the program");
int searchkey= input.nextInt(); // Only integers are allowed
System.out.println("Enter the search key: ");
String exit = input.nextLine(); //Introduce any string, like exit or apples.
System.out.println will not know what you are going to do, that is something that is meaningful for you, no for the program itself.
This is your current output:
Enter -1 to exit the program
Enter the search key:
<here you should type an integer and enter>
<here you should type a String>
It seems that you don't need the integer at all, but a proper output ought be:
Enter -1 to exit the program
<here you should type an integer and enter>
Enter the search key:
<here you should type a String>
After calling nextInt or nextLine, your console will stop printing until you enter something. If you enter "exit" when nextInt was called you will get that exception, just try to do the math "exit"+5.

How to use multiple Input Dialogs (New to Java)

I am trying to create a program that asks a user for a sentinel value (a value to enter when they want to end the list). It then asks the user to enter numbers until they re-enter the sentinel value. It then figures out the max number in the list. I'm very new to Java, and whenever I run the program is just asks for the sentinel value then does nothing else (never pops up the second input dialog). I'm sure it's something simple that I'm doing wrong, but I can't figure it out. Thanks for any help.
import java.util.*;
import javax.swing.JOptionPane;
public class HW1 {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int number;
int max;
int sentinel;
int count=0;
JOptionPane.showInputDialog("Please enter a sentinel value: ");
sentinel=input.nextInt();
JOptionPane.showInputDialog("Please enter numbers. Enter" + sentinel +" to end.");
number = input.nextInt();
max = number;
while (number!=sentinel){
count +=1;
if (number>max)
max=number;
JOptionPane.showInputDialog("Please enter numbers. Enter" + sentinel +" to end.");
number = input.nextInt();
}
if (count!=0){
JOptionPane.showMessageDialog(null, "The max is:" + max);
}
}
}
You are mixing the ways to input data to your program. Let's begin:
Scanner input = new Scanner(System.in);
The line above allows you to catch data in the command line from the keyboard.
JOptionPane.showInputDialog("Please enter a sentinel value: ");
This Option Pane is showing correctly, you put a value and then nothing happens. This is because your program is waiting to input something in the command line
sentinel=input.nextInt();
When your program arrives to the line above, the input.nextInt() stops the program until you put something in the command line.
The correct way should be something like this:
sentinel = Integer.parseInt(JOptionPane.showInputDialog("Please enter a sentinel value: "));
number = Integer.parseInt(JOptionPane.showInputDialog("Please enter numbers. Enter" + sentinel +" value to end."));
And remove:
number = input.nextInt();
sentinel=input.nextInt();
I think the confusion is this:
the JOptionPane opens with an input dialog
when the option pane closes, whatever you put there is ignored
then the code goes to this line sentinel=input.nextInt();
which waits for input from the console (e.g. you need to go back to the console, type the number there and press enter, only then the program will advance, it will block untill you do)
I would change it to something like this:
String sentinelInput = JOptionPane.showInputDialog("Please enter a sentinel value: ");
sentinel= Integer.parseInt(sentinelInput);
(repeat for all places where you expect input)
An alternative solution is
Don't use the JOptionPane, and instead just System.out.println to print the user a request for input (instead of the popup dialog). Then you can and keep the existing input.nextInt() calls to collect it.
Just note that all interaction will be in the console, without any popup dialogs (which I actually prefer in terms of user experience, and also it will be working in non GUI machines such as a linux terminal...)

Categories

Resources