How do I catch a hasNextInt() String input exception? - java

In my java app, which is a simple TollMachine simulator, I must implement the try/catch code in my code. I managed to work around the String input on a hasNextInt prompt, but when I try doing the same using try/catch, I just can't get the program to go into the catch section. The program goes into an infinite loop as it is, and I really need to get it to work with the try/catch method. Otherwise, I used an if(hasNextInt)/else(workaround) to get rid of the string input and prevent the infinite loop.
public class TollMachine {
static boolean running = true; //variable to control whether the program should run
static int userInput = -1; //variable to store the user's input
static String userInput2 = ""; //variable to store the input in case user does not enter an integer
static int motoTicketCount = 0; //variable to store the number of tickets sold(moto)
static int carTicketCount = 0; //variable to store the number of tickets sold(car)
static int vanTicketCount = 0; //variable to store the number of tickets sold(van)
static int truckTicketCount = 0;//variable to store the number of tickets sold(truck)
static int totalTicketCount = 0;//variable to store the number of total tickets sold
static Scanner keyb = new Scanner(System.in); //variable to detect the user's input
public static void main(String[] args) {
while (userInput != 0) //runs while userInput != 0
{
//This is the main menu, the user is prompted to choose an option
System.out.println("1. Motorcycle");
System.out.println("2. Car");
System.out.println("3. Van");
System.out.println("4. Truck");
System.out.println("5. Display total tickets sold.");
System.out.println("0. Exit");
try {
if (keyb.hasNextInt()) //checks whether the user inputs an integer
{
userInput = keyb.nextInt(); //stores the user's input to the userInput
if (userInput > 5 || userInput < 0) //if one of these conditions are true, the user selected an option
{ //that is not mentioned
System.out.println("Invalid input."); //displays the Invalid input error
} else {
//checks which option the user chose with multiple "if" conditions
if (userInput == 1) {
//Displays an appropriate message to the user, and increases the two counters by 1
System.out.println("Here is your motorcycle ticket.");
motoTicketCount++;
totalTicketCount++;
}
if (userInput == 2) {
//Displays an appropriate message to the user, and increases the two counters by 1
System.out.println("Here is your car ticket.");
carTicketCount++;
totalTicketCount++;
}
if (userInput == 3) {
//Displays an appropriate message to the user, and increases the two counters by 1
System.out.println("Here is your van ticket.");
vanTicketCount++;
totalTicketCount++;
}
if (userInput == 4) {
//Displays an appropriate message to the user, and increases the two counters by 1
System.out.println("Here is your truck ticket.");
truckTicketCount++;
totalTicketCount++;
}
if (userInput == 5) {
//Displays how many of each ticket were sold, and the total number of tickets sold
System.out.println("Motorcycle tickets sold: " + motoTicketCount);
System.out.println("Car tickets sold: " + carTicketCount);
System.out.println("Van tickets sold: " + vanTicketCount);
System.out.println("Truck tickets sold: " + truckTicketCount);
System.out.println("Total tickets sold: " + totalTicketCount);
}
if (userInput == 0) {
running = false; //terminates the program
}
}//end of else after the if (hasNextInt())
}//end of first if (hasNextInt())
}//end of try
catch (Exception e) //this SHOULD catch an invalid input error
{
System.out.println("Invalid input."); //displays invalid input in case the
userInput2 = keyb.next(); //discard the bad input
}
}
}
}

In here:
if (userInput >5 || userInput<0) //if one of these conditions are true, the user selected an option
{ //that is not mentioned
System.out.println("Invalid input."); //displays the Invalid input error
}
Change the System.out.println... to Throw new Exception("Invalid input.");
Note: this isn't really the correct use of an exception, but it may help you understand it.
in your catch block:
catch(Exception ex){
System.out.println(ex.toString());
}
EDIT: To try to understand the concept of the exception I would encourage you to try to change your input check to if(keyb.hasNext()) and then trying to cast the input to an integer with Integer.parseInt(keyb.next()); in your try block and catching the resultant NumberFormatException.
Also, rather than using the userInput2 variable to store the erroneous data you can just set userInput = -1; to restart the loop in your catch function.
Full code:
public class TollMachine
{
static boolean running = true; //variable to control whether the program should run
static int userInput = -1; //variable to store the user's input
static String userInput2 = ""; //variable to store the input in case user does not enter an integer
static int motoTicketCount = 0; //variable to store the number of tickets sold(moto)
static int carTicketCount = 0; //variable to store the number of tickets sold(car)
static int vanTicketCount = 0; //variable to store the number of tickets sold(van)
static int truckTicketCount = 0;//variable to store the number of tickets sold(truck)
static int totalTicketCount = 0;//variable to store the number of total tickets sold
static Scanner keyb = new Scanner(System.in); //variable to detect the user's input
public static void main(String[] args)
{
while (userInput != 0) //runs while userInput != 0
{
//This is the main menu, the user is prompted to choose an option
System.out.println("1. Motorcycle");
System.out.println("2. Car");
System.out.println("3. Van");
System.out.println("4. Truck");
System.out.println("5. Display total tickets sold.");
System.out.println("0. Exit");
try
{
/**
THIS THROWS YOUR EXCEPTION
**/
if (keyb.hasNext())
{
userInput = Interger.parseInt(keyb.next()); //stores the user's input to the userInput
if (userInput >5 || userInput<0) //if one of these conditions are true, the user selected an option
{ //that is not mentioned
System.out.println("Invalid input."); //displays the Invalid input error
}
else
{
//checks which option the user chose with multiple "if" conditions
if (userInput == 1)
{
//Displays an appropriate message to the user, and increases the two counters by 1
System.out.println("Here is your motorcycle ticket.");
motoTicketCount++;
totalTicketCount++;
}
if (userInput == 2)
{
//Displays an appropriate message to the user, and increases the two counters by 1
System.out.println("Here is your car ticket.");
carTicketCount++;
totalTicketCount++;
}
if (userInput == 3)
{
//Displays an appropriate message to the user, and increases the two counters by 1
System.out.println("Here is your van ticket.");
vanTicketCount++;
totalTicketCount++;
}
if (userInput == 4)
{
//Displays an appropriate message to the user, and increases the two counters by 1
System.out.println("Here is your truck ticket.");
truckTicketCount++;
totalTicketCount++;
}
if (userInput == 5)
{
//Displays how many of each ticket were sold, and the total number of tickets sold
System.out.println("Motorcycle tickets sold: "+motoTicketCount);
System.out.println("Car tickets sold: "+carTicketCount);
System.out.println("Van tickets sold: "+vanTicketCount);
System.out.println("Truck tickets sold: "+truckTicketCount);
System.out.println("Total tickets sold: "+totalTicketCount);
}
if (userInput == 0)
{
running = false; //terminates the program
}
}//end of else after the if (hasNextInt())
}//end of first if (hasNextInt())
}//end of try
catch (NumberFormatException e) //this SHOULD catch an invalid input error
{
System.out.println("Invalid input."); //displays invalid input in case the
userInput = -1;
}
}
}
}
At work, so if what I gave you is super broken its because I can't compile and test right now. But this should give you the right idea.

Related

Q: Doing multiple loops and multiple if-statements and if-else-statements | RENTAL CAR CALCULATOR PROJECT

my instructions on the project were as followed:
Instructions: Use a sentinel value loop. To create a basic Rental Car Calculator
Ask each user for:
Type of vehicle (May use something other than strings, such as: 1 for an economy, 2 for a sedan, etc.) Days rented Calculate the (For each customer):
Rental cost, Taxes, Total Due. There are three different rental options with separate rates: Economy # 31.76, sedan # 40.32, SUV # 47.56. [Note: only whole day units to be considered (no hourly rates)].
Sales tax is = to 6% on the TOTAL.
Create summary data with:
The number of customers Total money collected. Also, Include IPO, algorithm, and desk check values (design documents).
{WHAT I HAVE GOING AND MY QUESTION(S)}
package tests;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Tester {
public static void main(String []args){
int count=0;
int days;
int cus;
int carType;
double dailyFee=0, nonTaxTotal, total,fullTotal=0;
boolean checkRunOrQuit = false, chooseTypeVehicle = false, numberOfDAysChosen = false;
Scanner in=new Scanner(System.in);
while ( !checkRunOrQuit ) {
System.out.print("Press 1 to enter Rental Calculator or else press 0 to quit\n");
System.out.println("Please only enter 1 or 0. Also, please only enter number(s) not letter(s)");
try {
cus=in.nextInt();
switch ( cus ) {
case 0: System.out.println("End of application");
System.exit(0); // This will actually end your application if the user enters 0, no need to verify later on
break;
case 1: checkRunOrQuit = true;
break;
default:
System.out.println("Number must be either 1 or 0");
}
} catch (InputMismatchException ex) {
System.out.println("Invalid entry: ");
in.next();
}
}
while( !chooseTypeVehicle ) { // --> simplified comparison
count++;
System.out.print("What vehical would you like to rent?\n");
System.out.println("Enter 1 for an economy car");
System.out.println("Enter 2 for a sedan car");
System.out.println("Enter 3 for an SUV");
try {
carType = in.nextInt();
chooseTypeVehicle = true;
switch ( carType ) {
case 1: dailyFee = 31.76;
break;
case 2: dailyFee = 40.32;
break;
case 3: dailyFee = 47.56;
break;
default:
System.out.print("Number must be 1-3\n");
System.out.println("Please enter 1 for an economy car");
System.out.println("Enter 2 for a sedan car");
System.out.println("Enter 3 for an SUV");
chooseTypeVehicle = false;
break;
}
} catch (InputMismatchException ex) {
System.out.println("Answer must be a number");
in.next(); // -> you forgot this one.
}
}
while ( !numberOfDAysChosen ) {
try {
System.out.print("Please enter the number of days rented. (Example; 3) : ");
days = in.nextInt();
if (days <= 0) {
System.out.println("Number of days must be more than zero");
} else {
nonTaxTotal = (dailyFee * days);
total = (nonTaxTotal * 1.06);
fullTotal+=total;
numberOfDAysChosen = true;
}
} catch(InputMismatchException ex) {
System.out.println("Answer must be a number");
in.next();
}
}
in.close();
System.out.println("Count of customers : " + count);
System.out.printf("total of the Day : $ %.2f", fullTotal);
}
}
How would I make this program loop back to prompting the user: "Press 1 to enter Rental Calculator or else press 0 to quit\". After the "days rented input is entered?
[Note: Once the days rented is input, I was wanting a total calculation but not a summary. However, I want the summary info when the program is exited.]

Scanner object does not return intended result

I am trying to use the scanner object to validate some user input. According to my requirement if user input is 100>inputs<0 I need to provide some console output. However, the following code does not work when I enter 100/0 and provides me some empty console output. I tried to test this code block with 102 and -1 with same (empty) console output
public int validateScore(Scanner sc) {
int score = 0;
System.out.println("Please Enter Student's Score.");
for (;;) {
if (!sc.hasNextInt()) {
System.out.println("Please enter the score and in number");
sc.next(); // discard
}else if (sc.nextInt() > 100){
sc.next(); // discard
System.out.println("Please enter the score and in number in between 0-100 only: ");
}else if (sc.nextInt() < 0){
sc.next(); // discard
System.out.println("Please enter the score and in number in between 0-100 only: ");
}else {
score = sc.nextInt();
break;
}
}
return score;
}
The error is causing because of using nextInt() in the if else block . Use the method hasNextInt() and store the value in a temporary variable before validating the value .
You should not read from the Scanner several times. Just read the number once via nextInt into the variable and check it. Otherwise on every if branch you will be prompted for a new number.
public int validateScore(Scanner sc) {
int score = 0;
System.out.println("Please Enter Student's Score.");
for (;;) {
if (!sc.hasNextInt()) {
System.out.println("Please enter the score and in number");
sc.next(); // discard
} else {
int nextInt = sc.nextInt();
if (nextInt > 100) {
System.out.println("Please enter the score and in number in between 0-100 only: ");
} else if (nextInt < 0) {
System.out.println("Please enter the score and in number in between 0-100 only: ");
} else {
score = nextInt;
break;
}
}
}
return score;
}

Program printing incorrectly to console

I created a program which asks the user for an input (grade). I am using try/catch statements to catch InputMismatchException, in case the user enters an incorrect data type. The problem occurs during the second try/catch statement. After the program asks "Enter your percentage mark?" in the if statement and the user enters an incorrect data type. The program then reprints your grade twice and do you want to enter your grade twice.
import java.util.InputMismatchException;
import java.util.Scanner;
public class CatchingException {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int score;
String choice;
try {
System.out.println("Enter your percentage mark: ");
score = scan.nextInt();
do {
if(score <40) {
System.out.println("You FAILED");
}else if(score >=40 && score <50){
System.out.println("Your grade: PASS MARK");
}else if(score >=50 && score <60) {
System.out.println("Your grade: 2:2");
}else if (score >=60 && score <70) {
System.out.println("Your grade: 2:1");
}else {
System.out.println("Your grade: 1:1");
}
System.out.println("Do you want to enter another grade: ");
choice = scan.next();
if(choice.equalsIgnoreCase("yes")) {
try{
System.out.println("Enter your percentage mark: ");
score = scan.nextInt();
}catch(InputMismatchException e) {
System.err.print("Incorrect Input");
}
}
}while(!choice.equalsIgnoreCase("No"));
}catch(InputMismatchException e) {
System.err.println("Incorrect Input ");
}
System.out.println("program terminated");
scan.close();
}
}
Your catch block does not transfer control. (e.g, by returning or throwing another exception) This means that after the message is printed, the program checks the while condition. Since that condition will never be true in this situation, it will rerun the loop using the old score.
The statement that would have updated the score threw an exception, so it wasn't updated.
You need to keep on repeating asking percentage from user if user enters incorrect input data to it.
Right now, it catches exception and then enter's the do while loop and hence prints the grade once again. You might need to do the following:
do {
System.out.println("Enter your percentage mark: ");//inner one
try{
score = scan.nextInt();
}catch(InputMismatchException e) {
System.err.print("Incorrect Input");
score = -1;
}
}while(score == -1);
So you loop until score is -1 (score cant be negative in exam and hence -1). So next time when you run it with invalid input, it will catch the exception and set score as -1 and then check for while condition which will satisfy and hence will again start from do i.e. asking user to input percentage.
A note: If you input an invalid number (say a string) when you first enter score then your program will terminate after printing "Incorrect Input " onto error console.
It should be while(choice.equalsIgnoreCase("No")); and not while(!choice.equalsIgnoreCase("No"));
Fixed it! Give it a try now.
import java.util.InputMismatchException;
import java.util.Scanner;
public class CatchingException {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int score;
String choice;
try {
System.out.println("Enter your percentage mark: ");
score = scan.nextInt();
do {
if(score <40) {
System.out.println("You FAILED");
}else if(score >=40 && score <50){
System.out.println("Your grade: PASS MARK");
}else if(score >=50 && score <60) {
System.out.println("Your grade: 2:2");
}else if (score >=60 && score <70) {
System.out.println("Your grade: 2:1");
}else {
System.out.println("Your grade: 1:1");
}
System.out.println("Do you want to enter another grade: ");
choice = scan.next();
if(choice.equalsIgnoreCase("yes"))
System.out.println("Enter your percentage mark: ");{
try{
score = scan.nextInt();
}catch(InputMismatchException e) {
System.err.print("Incorrect Input");
}
}
}while(choice.equalsIgnoreCase("No"));
}catch(InputMismatchException e) {
System.err.println("Incorrect Input ");
}
System.out.println("program terminated");
scan.close();
}
}

How do i make the program keep looping until the user has entered an integer

i am trying to modify my program so that even when the user has entered a string instead of the program crashing it should keep looping and asking for the user to enter the exam grade which needs to be an integer, only when the user has entered an integer should the program terminate. I am referring to the code in the do-while block
import java.util.InputMismatchException;
import java.util.Scanner;
public class CatchingException {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int score;
String choice;
try {
System.out.println("Enter your percentage mark: ");
score = scan.nextInt();
do {
if(score <40) {
System.out.println("You FAILED");
}else if(score >=40 && score <50){
System.out.println("Your grade: PASS MARK");
}else if(score >=50 && score <60) {
System.out.println("Your grade: 2:2");
}else if (score >=60 && score <70) {
System.out.println("Your grade: 2:1");
}else {
System.out.println("Your grade: 1:1");
}
System.out.println("Do you want to enter another grade: ");
choice = scan.next();
if(choice.equalsIgnoreCase("yes")) {
System.out.println("Enter your percentage mark: ");
score = scan.nextInt();
System.err.println("Incorrect Input");
}
}while();
}catch(InputMismatchException e) {
System.err.println("Incorrect Input ");
}
System.out.println("program terminated");
scan.close();
}
}
Use a boolean variable to keep track of whether or not to keep looping. For example:
boolean loop = true;
do {
// set loop to false when you want to end
} while(loop);
so you could do:
int score = null;
boolean isInt = false;
do {
System.out.println("Enter your percentage mark:");
try {
score = scan.nextInt();
isInt = true;
} catch (InputMismatchException e) {
//Not An Integer
isInt = false;
}
} while(false)
//Do you if statements here if it gets out of the while loop which means the user entered an int
Instead of assuming the number inputed is an int, you can input it as a String and loop until that string represents an int:
int intScore;
String score;
boolean gotInt = false;
while (!gotInt) {
score = scan.next();
try {
intScore = Integer.valueOf(score);
gotInt = true;
} catch (NumberFormatException e) {
// output some warning
}
}
Did you consider using JOptionPane to get an input from the user? It is able to display a little window with a text field and a OK and Cancel button which would fit your needs perfectly.
Here is the documentation for JOptionPane#showInputDialog:
static String showInputDialog(Component parentComponent, Object message, String title, int messageType)
Shows a dialog requesting input from the user parented to parentComponent with the dialog having the title title and message type messageType.

Java - While loop for menu selection (console based program)

Update
The first time the user makes a choice such as "1" the menu is displayed again. The next time a selection is made the payment information begins to cycle. After the cycling is complete and the menu is displayed again, it works as it should. Also, the first two years are output instead of just the first when a selection begins to cycle, but then outputs one year at a time as intended.
//create scanner object for choosing a loan, then prompt for and accept input
Scanner choose = new Scanner(System.in);
String choice;
System.out.println("\nType 1, 2, or 3 and press enter to see the monthly payment information for the respective loan. To end the program type \"end\".");
choice = choose.next();
//cycle loan 1 payment information
//create scanner object to advance to the next year's payments
//loop for cycling payment information
//initialize loan principal to variable
while (!"end".equals(choice)) {
System.out.println("\nType 1, 2, or 3 and press enter to see the monthly payment information for the respective loan. To end the program type \"end\".");
choice = null;
choice = choose.next();
if ("1".equals(choice)) {
//calculation code
}
if (j < 6) {
System.out.println("Press enter to get the mortgage information for year " + (j + 2));
choice = choose.nextLine();
} else {
System.out.println("Congratulations, your mortgage has been paid off.");
}
}
choice = null;
}
if ("2".equals(choice)) {
//calculation code
}
if (j < 14) {
System.out.println("Press enter to get the mortgage information for year " + (j + 2));
choice = choose.nextLine();
} else {
System.out.println("Congratulations, your mortgage has been paid off.");
}
}
choice = null;
}
if ("3".equals(choice)) {
//calculation code
}
if (j < 29) {
System.out.println("Press enter to get the mortgage information for year " + (j + 2));
choice = next.nextLine();
} else {
System.out.println("Congratulations, your mortgage has been paid off.");
}
}
choice = null;
}
}
choose.close();
}
}
I can see three issues upfront:
You don't need two scanners for System.in stream. Remove this statement Scanner next = new Scanner(System.in); and use the choose instance.
If you close your input scanner as next.close();, it closes your input stream System.in as well and you may not be able read the stream again. Make sure you close the stream only when you are completely done with your program.
Use equals method to compare the condition in while as while(!"end".equals(choice)). Put the literal "end" as first argument will take care of the null value of choice.
EDIT:
Your modified code at high level:
Scanner choose = new Scanner(System.in);
String choice= null;
int j = 0;
while (!"end".equals(choice)) {
System.out.println("\nType 1, 2, or 3 and press enter to see the monthly payment information for the respective loan. To end the program type \"end\".");
choice = choose.nextLine();
if ("1".equals(choice)) {
//calculation code
if (j < 6) {
System.out.println("Press enter to get the mortgage information for year " + (j + 2));
choice = choose.nextLine();
} else {
System.out.println("Congratulations, your mortgage has been paid off.");
}
choice = null;
}
if ("2".equals(choice)) {
if (j < 14) {
System.out.println("Press enter to get the mortgage information for year " + (j + 2));
choice = choose.nextLine();
} else {
System.out.println("Congratulations, your mortgage has been paid off.");
}
choice = null;
}
if ("3".equals(choice)) {
if (j < 29) {
System.out.println("Press enter to get the mortgage information for year " + (j + 2));
choice = choose.nextLine();
} else {
System.out.println("Congratulations, your mortgage has been paid off.");
}
choice = null;
}
}
choose.close();
One bug is that String equality isn't the same as ==. You should use .equals():
while (!choice.equals("end")) {
Hope that helps!
You're setting choice to null, so choice != "end" is always true.
Move the next.close(); choice = null to outside the while loop.
Also, what weolfe91 said.
import java.util.Scanner;
class Main
{
public static void main(String [] args)
{
Scanner sc=new Scanner(System.in);
System.out.println("Enter no.1:");
int a=sc.nextInt();
System.out.println("Enter no.2:");
int b=sc.nextInt();
boolean exit=false;
do
{
System.out.println("1.addition");
System.out.println("2.subtraction");
System.out.println("3.multiplication");
System.out.println("4.division");
System.out.println("5.exit");
System.out.println("choose one!");
Scanner sd=new Scanner(System.in);
System.out.println("enter your choice");
int num=sd.nextInt();
switch(num)
{
case 1:
int add=a+b;
System.out.println("addition="+add);
System.out.println("\n");
break;
case 2:
int sub=a-b;
System.out.println("subtraction="+sub);
System.out.println("\n");
break;
case 3:
int mul=a*b;
System.out.println("multilpication="+mul);
System.out.println("\n");
break;
case 4:
int div=a/b;
System.out.println("division="+div);
System.out.println("\n");
break;
case 5:
exit=true;
break;
}
}while(!exit);
}
}

Categories

Resources