Switch statement with Try Catch Exception Java - java

I've got a main menu I'm creating for a program using a switch statement. I'm try to set up Try and Catch Exception so that if a user enters a String rather than an Int, the program will tell the user this is not valid and prompt them to try again.
So far, I have gotten it to tell the user this is not valid whenever this occurs, but it is unable to go back and take an input from the user.
Here is my code:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Subscription Manager:");
System.out.println("\n1. Enter new Subscription");
System.out.println("2. Display Summary of subscriptions");
System.out.println("3. Display Summary of subscription for Selected Month");
System.out.println("4. Find and display subscription");
System.out.println("0. Exit");
System.out.print("Please choose one of the options to proceed:");
try {
int choice = sc.nextInt();
switch (choice) {
case 1:
System.out.println("1. Enter new Subscription");
break;
case 2:
System.out.println("2. Display Summary of subscriptions");
break;
case 3:
System.out.println("3. Display Summary of subscription for Selected Month");
break;
case 4:
System.out.println("4. Find and display subscription");
break;
case 0:
System.out.println("Exiting Program...");
System.out.println("Goodbye!");
System.exit(1);
break;
default:
System.out.println("ERROR. Enter a selection from the options to continue!");
break;
}
} catch (InputMismatchException e) {
System.out.println("Enter a numerical value!");
sc.nextLine();
}
}
}
I have tried adding a do while loop, but I am met with the same issue still.
Thank you for reading!

What you need to do is to use a loop with the correct exit condition. For this specific case, I would recommend using do..while loop. Because this looks like a school assignment, I am not going to give you the full code but a small pseudocode.
int choice = 9999; // Declare this outside the do while loop so that you can access this variable in the while exit clause.
// Also initialize this so that you still have a value for choice in case of exception
do {
try {
int choice = sc.nextInt();
// DO YOUR SWITCH CASE AS YOU HAVE
}
catch(InputMismatchException e) {
// IN this case, choice is still 9999 for an error in the first run and some other integer in the subsequent runs of the loop. Just print an error message.
}
} while (choice != 0);

Related

how do i keep taking choices in switch case until exit choice is entered in java [duplicate]

This question already has an answer here:
How to use java.util.Scanner to correctly read user input from System.in and act on it?
(1 answer)
Closed 4 years ago.
I want to keep taking choices from the user until he gives an exit statement.
How can I come out of the while loop if I use it in this code?
Is there any other way to take choice from the user than switch case:
And if I try to use while loop for this then it is going in an infinite loop:
Code:
import java.util.Scanner;
class lib
{
public static void main(String args[])
{
Scanner in=new Scanner(System.in);
String c;
int j=5,a=5,s=5,cg=5;
int d=0;
System.out.println("Available Copies :");
System.out.println("java=5,ada=5,sp=5,cg=5");
System.out.println("enter book title");
//System.out.println("enter exit for exit if don't want to search");
c=in.nextLine();
while(d==0)
{
switch(c)
{
case "java":
System.out.println("author is herbert");
System.out.println("price :500");
j--;
break;
case "ada":
System.out.println("author is corman");
System.out.println("price :600");
a--;
break;
case "sp":
System.out.println("author is dhamdhire");
System.out.println("price :550");
s--;
break;
case "cg":
System.out.println("author is pearson");
System.out.println("price :700");
cg--;
break;
case "exit":
d++;
break;
default:
System.out.println("book not available");
}
}
if(j!=0)
System.out.println("number of available copies is"+j);
}
If you want to keep taking input from the user until they give the exit command then you need to keep taking input inside the while loop. Move c=in.nextLine() into the while loop right before the switch statement.
If you want to prompt the user as well then add a print statement at the end of the loop right after the switch statement ends, and instead move c=in.nextLine() to the end of the while loop right after the print statement. Something like:
System.out.print("Enter the title of another book: ");
c=in.nextLine();
I think what your looking for is moving your nextLine inside the while loop.
This part of the code:
//System.out.println("enter exit for exit if don't want to search");
c=in.nextLine();
while(d==0)
{
.....
To this:
//System.out.println("enter exit for exit if don't want to search");
while(d==0)
{
c=in.nextLine();
.....

Endless loop in a text menu when handling InputMismatchException

I have a homework assignment to create a class with a looping menu to manage a queue of cars. We learned queues in our last class.
My menu works perfectly fine until it catches InputMismatchException or QueueEmptyException, after which it goes into endless loop, not even stopping at the userInput.nextInt();. It works when it catches QueueFullException, but not the others.
My code is:
import java.util.*;
public class CarQueueManagement {
public static void main(String[] args) throws InputMismatchException, QueueFullException{
ArrayQueue queue = new ArrayQueue(3);;
Scanner userInput = new Scanner(System.in);
int carNum;
int choice = 0;
queue.add(1);
OUTER:
while (true) {
try{
System.out.println("ΜΕΝΟΥ:\n\t1. Άφιξη αυτοκινήτου");
System.out.println("\t2. Αναχώρηση αυτοκινήτου\n\t3. Κατάσταση ουράς\n\t4. Έξοδος");
System.out.print("\n\tΕπιλογή (1-4): ");
choice = userInput.nextInt();
switch (choice){
case 1:
System.out.print("\n\tΆφιξη αυτοκινήτου:\n\t\tΑριθμός Αμαξιού");
carNum = userInput.nextInt();
queue.add(carNum);
break;
case 2:
if(queue.isEmpty()){
System.out.println("\n\tΗ ουρά είναι άδεια, δεν χριάζεται διαγραφή.\n\n");
break;
}
String answer;
while(true){
System.out.print("\n\tΑναχώρηση αυτοκινήτου\n\t\tΕπιβεβαίωση; (y/n): ");
answer = userInput.next();
if(answer.equals("y")){
queue.remove();
break;
}
else if(answer.equals("n"))
break;
}
break;
case 3:
System.out.println("\n\tΚατάσταση ουράς:");
if(queue.isEmpty()) System.out.println("\t\tΗ ουρά είναι άδεια.\n\n");
else if(queue.isFull()) System.out.println("\t\tΗ ουρά είναι γεμάτη.\n\n");
else System.out.println("\t\tΗ ουρά έχει άδιες θέσοις.\n\n");
break;
case 4:
System.out.print("\n\nΕξοδος");
break OUTER;
default:
break;
}
}catch (InputMismatchException exc){
System.out.println("\t\tΛΑΘΟΣ ΕΙΣΑΓΩΓΗ\n");
}catch(QueueEmptyException exc){
System.out.println("\t\t" + exc.getMessage() + "\n");
}catch(QueueFullException exc){
System.out.println("\t\t" + exc.getMessage() + "\n");
}
}
}
}
From the intro section of java.util.Scanner docs (emphasis mine):
When a scanner throws an InputMismatchException, the scanner will not pass the token that caused the exception, so that it may be retrieved or skipped via some other method.
Without the details, your while(true) loop is:
while (true) {
try{
choice = userInput.nextInt();
switch (choice){
case 1:
...
}
} catch (InputMismatchException exc){
// Do nothing.
}
}
When the user enters something that can't be converted to an integer, the Scanner throws an InputMismatchException, which you catch and ignore. Then the while loop goes back to the top, where it tries to execute userInput.nextInt()... but the Scanner is still looking at the same invalid input, so it immediately throws another InputMismatchException, which you catch and ignore again. Execution continues at the top of the while loop, where it calls nextInt() again... and the cycle continues forever.
You have to force the Scanner to skip the bad input, so your catch block should look something like this:
}catch (InputMismatchException exc){
System.out.println("\t\t[chastise the user in Greek]\n");
userInput.next(); // Skip invalid input.
}
Other Advice
As a general rule, lots of small methods are easier to understand than one large method. The nested while loops and switch statement were especially hard to follow. I was only able to find the bug by breaking that gigantic main method into many smaller, private static methods.
At the very least, each menu item could be handled in its own method. I also got rid of the break label by putting the whole menu into a separate method, which returned a boolean indicating whether the user was done or not. That reduced the whole loop inside main to:
boolean done = false;
while (! done) {
try{
done = handleUserInput(queue, userInput);
} catch (InputMismatchException exc) {
System.out.println("\nINPUT ERROR\n");
userInput.next();
} // Other catch blocks as before...
}
My handleUserInput doesn't do much --- it gets user input, determines which method should handle that input, and then returns true or false... It could be made simpler than this, too.
private static boolean handleUserInput(
final ArrayQueue queue,
final Scanner userInput
) {
boolean done = false;
printMenu();
int choice = userInput.nextInt();
switch (choice) {
case 1:
addToQueue(queue, userInput);
break;
case 2:
removeFromQueue(queue, userInput);
break;
case 3:
displayQueue(queue);
break;
case 4:
printExitMessage();
done = true;
break;
default:
break;
}
return done;
}
Splitting the various menu activities into separate methods made them much easier to follow. For example, when the logic was all mixed together in main, it was hard to tell if variables like carNum or answer were part of the problem. In this version, carNum is a local variable trapped inside the addToQueue method, so when I'm working anywhere else, I can completely ignore it.

While loop not cancelling out

I've ran into a weird issue.
I'm trying to make this code loop constantly until the user enters 4; when the user enters 4, I want to make it so that 'Quit_Detect' is set to false.
For some reason, it doesn't let me do that. The code still continuously loops until it is stopped manually.
Below is all of the code that I have used for this program along with some comments.
import java.util.Scanner; // Imports the scanner utility.
public class Start {
public static void main(String[] args) {
Scanner Reader = new Scanner(System.in); // Creates a new scanner.
#SuppressWarnings("unused")
boolean Quit_Detect;
Quit_Detect = true;
while (Quit_Detect = true)
{
int input; // States that input will have a datatype of 'int', or integer. Or, a whole number.
System.out.println("Please input your option.");
System.out.println("1. Door with a crack in it");
System.out.println("2. Normal Wooden Door");
System.out.println("3. Turn around");
System.out.println("4. Quit");
input = Reader.nextInt(); // Has the user define what the variable 'input' will be set to.
switch (input) // Uses the Variable 'input' to detect what case to follow.
{
case 1:System.out.println("First Option");
break;
case 2:System.out.println("Second Option");
break;
case 3:System.out.println("Third Option");
break;
case 4:Quit_Detect = false;
break;
default:System.out.println("Invalid option."); //Prints this if the user inputs any number other than 1, 2, or 3.
}
}
}
}
You should use:
while (Quit_Detect)
instead of:
while (Quit_Detect = true)
The first statement checks if Quit_Detect is true where the second sets the value of Quit_Detect to true.

Calling previous switch in Java

I'm making a simple command line system where the user is supposed to be able to choose what they want to do. Therefore I've made a switch that takes a number as input and outputs whatever I choose, although I have now clue on how to return the user to the place where they can input again.
Let's say two of the cases looks like this:
case 6:
System.out.println("----- List of available Systems: ----- ");
break;
default:
System.out.println("You pressed a non-existing number. Please try again.");
break;
}
Now if the user (me) types any number above 6 it goes to the default and stops there. Is there anyway to make it jump back to the first "Menu" that asks for input?
Thank you in advance.
You can wrap it in a loop, e.g. a while:
while (var < 1 || var > 6) {
switch(var) {
...
}
}
However, this way, you need to make sure, that you won't be stuck in an infinite loop. This can be solved, e.g. by using a label:
end: while (var < 1 || var > 6) {
switch (var) {
case 1:
// do something
break end;
...
default:
System.out.println("Please try again.");
break;
}
}
This way, the break statements will break out of the while loop. Java labels are basically a very limited version of goto.
How about something more verbal..
int myno;
Scanner scanner =new Scanner(System.in);
boolean exit = false;
while(!exit){
System.out.println("1. Menu 1");//Modify your menu
System.out.println("2. Menu 2");
System.out.println("3. Menu 3");
System.out.println("4. Menu 4");
System.out.println("5. Menu 5");
System.out.println("6. Menu 6");
myno = scanner.nextInt();
switch(myno){
case 1 :
//do something
break;
case 2 :
//do something
break;
case 3 :
//do something
break; //add for remaining cases
case 7 :
exit = true;//for exit
break;
default :
// do something //set exit = true if you what to end the program for other inputs
}
}
try this

Switch returning same statement multiple times

I'm making a school assignment and this time around I thought about using a switch statement since it looked more efficient.
It's just something basic but if I enter a letter for example and after that number 1 for example it would return case 1 twice?
This is my code for the entire class so far:
import java.util.InputMismatchException;
import java.util.Scanner;
public class Test {
private int option;
public static void main(String[] args) {
Test t = new Test();
t.start();
t.optionMenu();
}
public void start() {
System.out.println("Make your choice:");
System.out.println("1: Play");
System.out.println("2: Options");
System.out.println("3: Exit");
}
public void optionMenu() {
try {
Scanner sc = new Scanner(System.in);
this.option = sc.nextInt();
System.out.println(this.option);
} catch (InputMismatchException e) {
System.out.println("Please enter a number");
optionMenu();
}
switch (this.option) {
case 1:
System.out.println("Game starting...");
break;
case 2:
System.out.println("Loading options");
break;
case 3:
System.out.println("Game exiting...");
System.exit(0);
break;
default:
System.out.println("Enter a valid number (1, 2 or 3");
break;
}
}
}
Any help would be much appreciated, thanks!
When you call sc.nextInt() without first asking if (sc.hasNextInt()), you are open to some strange behavior when end-users start typing unexpected input, such as letters. In this case the scanner would not advance its reading pointer, so your program will get stuck reading the same incorrect output.
To fix this issue, add a loop that "clears out" the invalid entry before attempting to read an int again, like this:
while (!sc.hasNextInt()) {
System.out.print("You need to enter an integer.");
sc.nextLine(); // Clear out the bad input
}
int val = sc.nextInt(); // At this point we know that sc.hasNextInt(), because that's the loop condition
Another point is that it is not a good idea to do with recursion what can be done with iteration: the recursive call to optionsMenu is going to accumulate as many levels of invocation as the number of times the end-user enters an incorrect value, so a very persistent user could theoretically force a stack overflow on your program by entering invalid data repeatedly.
Using the code fragment above would free you from the need to call optionsMenu recursively, and also from catching the input exception.
It's just something basic but if I enter a letter for example and after that number 1 for example it would return case 1 twice?
I'm not sure what you mean here. Firstly, your idea works, this code should be fine!
Second, if you enter anything besides just the number 1, 2, or 3, you will go to the "default:" block of code. Since you are prompting the user again if they fail, typing "a" or "a1" into the prompt just shows the menu again. The user needs to just type "1", "2", or "3" to successfully select a menu option.

Categories