Issue with some simple exception handling using .hasNextInt() in Java? - java

I'm creating an array list for a menu of food items which correspond to a number on a menu. Most of that is left out: my main issue is that the error message does not display for the first time the user does not enter an integer value. Nothing will show on the console after I press enter, but if I again enter something that isn't an integer it will work like it should and display the error message.
Edit: something else I should note is that earlier in the code I use the same scanner object so use .next() to clear it of the previous value it had.
orderArray = new String[length];
menuDisplay();
int item; //the item number that user must enter
for(int i=1; i<=length;i++)
{
System.out.println("Please choose item #"+ i+": ");
scan.next();
while(!scan.hasNextInt()) //this while loop checks that an integer value has been entered
{
System.out.println("Please enter an integer value from the above menu.");
scan.next();
}
}

The hasNextInt check the next token, not the token just received, so always call hasNextXxx() before calling nextXxx().
You'd also want to actually get the integer value and assign it to item.
Rearrange your code like this:
System.out.println("Please choose item #"+ i+": ");
while (!scan.hasNextInt()) //this while loop checks that an integer value has been entered
{
System.out.println("Please enter an integer value from the above menu.");
scan.next(); // skip bad token
}
item = scan.nextInt();

Related

How to Loop the prompt for user input if it is not a unique value in an ArrayList?

I am trying to have users input a UNIQUE value for a book's ISBN.
I am able to receive user input and it populates the ArrayList just fine, but if a user inputs a value that is already in the ArrayList, I want them to receive an error message and be prompted to try again.
do{
System.out.print("\n ISBN must be 4 numbers only.\nEnter isbn: ");
isbn = sc.nextLine();
try{
isbnInt = Integer.valueOf(isbn);
}//end try
catch(NumberFormatException nfe){
System.out.println("\nPlease enter integer numbers only.");
}//end catch
}while(isbn.trim().length() <4 && (isbn.trim().length()>0) || (isbn.trim().length() >4));
sc = new Scanner(System.in);
System.out.println();
do{
System.out.print("Enter quantity: ");
quantity = sc.nextLine();
try{
quantityInt = Integer.valueOf(quantity);
}//end try
catch(NumberFormatException nfe){
System.out.println("\nPlease enter integer numbers from 1 through 1000 only.");
}//end catch
}while(quantity.trim().length() > 1000 ||(quantity.trim().length()<0) );
Create a method to validate ISBN such as
public boolean verifyISBN(int ISBN)
Here you will check if ISBN exists in the arraylist by using a for loop
Upon receiving the return value store it in a variable and use in while condition of 1st do-while loop.
I think you're in need of a different data structure, like HashSet, because it doesn't allow duplicates.
When calling the add method:
hashSet.add(quantityInt);
It verifies if the HashSet already contains that element.
if it contains: it'll not insert the element and will return false;
if it doesn't contain: it'll insert the element and will return true.
You can check if the method returned false and if so, show an error message and enable the input again.
...
final Set<Integer> set = new HashSet<>();
int quantityInt = scanner.nextInt();
while(!set.add(quantityInt)) {
System.out.println("You can't insert duplicate elements.");
quantityInt = scanner.nextInt();
}
...
I feel like I am dialing in on it. Unfortunately I am required to use an ArrayList for the assignment.
I have a while loop setup with a boolean operator "contains"
while(contains != books.contains(isbnInt)){
But it isn't working

How to let the user input back to the former question

I write a code to let the user input cruise id first and then enter the ship name.
At first, I want to detect whether the user input integer type, if not, the user has to re-enter the first question again.
But in my code, it will directly print the second question instead of go back to the first question and ask again. Same, for the second question, I also want it return back and ask user to input again if the input is wrong
Please help me for that. Thanks!!
try{
System.out.println("Input Cruise ID:");
sc1 = sc.nextInt();
}catch(Exception e){
System.out.println("Please Enter integer:");
sc.nextLine();
}
System.out.println("Input ship name :");
try{
sc2 = sc.next();
}catch(Exception e){
if( sc2 != "Sydney1" || sc2 !="Melmone1"){
System.out.println("Oops!! We don't have this ship!! Please enter the ship name : Sydney1 or Melbone1");
}
}
I write a code to let the user input cruise id first and then enter the ship name. At first, I want to detect whether the user input integer type, if not, the user has to re-enter the first question again.
What you need is an input validation. try-catch block itself will not create an endless loop to reprompt the user should the input is not an integer. What you need is a while loop.
You can use a do-while loop as follows so that it runs first before performing a check:
String input = ""; //just for receiving inputs
do{
System.out.println("Input Cruise ID:");
input = sc.nextInt();
}while(!input.matches("[0-9]+")); //repeat if input does not contain only numbers
int cruiseID = Integer.parseInt(input); //actual curiseID in integer
To perform validation for your second input (i.e, your shipName, you need another while loop which encloses your prompt for input).
try-catch block are mainly used to handle exceptional cases. Try not to misuse it as a control statement for your implementations.
You can add more checks inside the while loop itself. For example, checking if the number is a negative number or zero etc. For example
while (true) {
try {
System.out.println("Input Cruise ID:");
cruiseId = sc.nextInt();
if(cruiseId <=0){
System.out.println("Please Enter integer:");
sc.nextLine();
}
break; // break when no exception happens till here.
} catch (Exception e) {
System.out.println("Please Enter integer:");
sc.nextLine();
}
}

Reset Values in ArrayList Nested in While Loop

I wrote code to store the values of user-inputted dollar amounts. Whenever the program prompts the user, "would you like to input items - y/n?" the user can then put in values stored in an ArrayList.
The initial prompt is below. It seems to work as I am able to put in values with no visible errors.
System.out.print("Would you like to input item/s - y/n: ");
String response = textReader.nextLine();
System.out.println();
// create while loop to restrict responses to single characters
while ((!response.equalsIgnoreCase("y")) && (!response.equalsIgnoreCase("n")))
{
System.out.print("Sorry - we need a y/n: ");
response = textReader.nextLine();
System.out.println();
}
But when I go to put in values a second time, I notice the program doesn't clear out the values from my first entry. The code I wrote to prompt the user for another cluster of values is identical to the code I wrote for the initial prompt. I nested these second prompt in a while loop triggered by the user selecting "y" to the initial prompt.
while ((response.equalsIgnoreCase("y")))
{
System.out.print("Please enter an item price, or -1 to exit: $");
double values = numberReader.nextDouble();
while ((values > (-1)))
{
cartItems.add(values);
System.out.print("Please enter another item price, or -1 to exit: $");
values = numberReader.nextDouble();
}
System.out.println();
System.out.println("********** Here are your items **********");
// I omitted the code here to make this more concise.
// prompt the user to input a second round of values
System.out.print("Would you like to input item/s - y/n: ");
response = textReader.nextLine();
System.out.println();
// create while loop to restrict responses to single characters
while ((!response.equalsIgnoreCase("y")) && (!response.equalsIgnoreCase("n")))
{
System.out.print("Sorry - we need a y/n: ");
response = textReader.nextLine();
System.out.println();
}
}
My output is below. When I am prompted a second time, I select 'y' to add more items. However, my newly added item $3.00, gets added to the list from the first prompt. Is there anyway to refresh or erase the ArrayList so that it is brand new each time the user wants to input new values?
cartItems.clear();
put it at the end of the loop, after the results are printed to the console.
It will refresh the list and remove all the elements within it.
In no place you are resetting the ArrayList.
You can call cartItems.clear() when you are done with your processing and you are looping for a next round (at the bottom of the outter while).
...
while ((!response.equalsIgnoreCase("y")) && (!response.equalsIgnoreCase("n")))
{
System.out.print("Sorry - we need a y/n: ");
response = textReader.nextLine();
System.out.println();
}
cartItems.clear();
}
Create instance of list in the while loop
List<Double> cartList = new ArrayList<Double>();
So now everytime user selects yes, the program enters in the while loop and then a new instance of list is created without any values. If you want to store the values in the previous list, write it to a persistence storage like file or database before creating a new instance of list.
Alternatively, you can also use
cartList.clear();
But, i don't recommend doing so.It can give you junk values and takes more amount of time. The clear method basically iterates over all the elements of list and does them null like this.
for(int i = 0; i < cartList.size(); i++){
cartList.get(i) = null;
}

Java: Try to Understand Getting Inputs from Users Using Scanner

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.

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