问题
I'm looking to keep the following menu repeating:
Choose an Option
1 - FIND
2 - IN-SHUFFLE
3 - OUT-SHUFFLE
So that when a user selects an option (and this will be executed), afterwards they can select other options as well.
Problem: My code keeps the menu repeating without stopping.
import java.util.Scanner;
public class MainMenu {
public static void main(String[] args) {
int userChoice;
userChoice = menu();
}
private static int menu() {
Scanner scanner = new Scanner(System.in);
System.out.println("Choose an Option");
System.out.println("1 - FIND");
System.out.println("2 - IN-SHUFFLE");
System.out.println("3 - OUT-SHUFFLE");
int choice = scanner.nextInt();
boolean quit = false;
do {
System.out.println("Choose an Option");
switch (choice) {
case 1:
System.out.println("\n1 - FIND\n");
//Deck.findTop();
break;
case 2:
System.out.println("\n2 - IN-SHUFFLE\n");
// call method
break;
case 3:
System.out.println("\n3 - OUT-SHUFFLE\n");
// call method
break;
default:
System.out.println("\nInvalid Option");
break;
}
}
while (!quit);
return choice;
}
}
I'm not sure how I can stop it from constantly repeating.
回答1:
One issue in your code is that method menu
returns an option, So it can either be used to read only an option from the console, or to do the whole dialog, until the user decides to quit. The latter is better IMHO because it keeps the display of the menu close to the switch
statemenmt:
private static void menu()
{
Scanner scanner = new Scanner(System.in);
System.out.println("Choose an Option");
System.out.println("1 - FIND");
System.out.println("2 - IN-SHUFFLE");
System.out.println("3 - OUT-SHUFFLE");
System.out.println("4 - QUIT");
boolean quit = false;
do {
System.out.println("Choose an Option");
int choice = scanner.nextInt();
switch (choice) {
case 1:
System.out.println("\n1 - FIND\n");
Deck.findTop();
break;
case 2:
System.out.println("\n2 - IN-SHUFFLE\n");
// call method
break;
case 3:
System.out.println("\n3 - OUT-SHUFFLE\n");
// call method
break;
case 4:
System.out.println("\n4 - QUIT");
quit = true;
break;
default:
System.out.println("\nInvalid Option");
break;
}
}
while (!quit);
}
回答2:
The selected option stays the same throughout the loop. You need to set quit
to true for the loop to exit.
I suggest adding an option to quit to the switch statement, where you do just that.
To be able to change the selected option, you need to ask for input inside the loop.
Scanner sc = new Scanner(System.in);
int choice;
boolean quit = false;
do {
choice = sc.nextInt();
switch (choice) {
case 1:
// case 1
break;
case 2:
// case 2
break;
case 3:
// case 3
break;
case 4:
quit = true;
break;
default:
// your default here
}
} while (!quit);
回答3:
What happens?
- User's choice (
int choice = scanner.nextInt();
) is only asked once before the loop. So thechoice
is fix before entering the loop. - Your
do {} while
loops only the switch-statement which executes some code, based on the user's choice (actually prints single fixed choice). The user has no chance to change this inside the loop. - The loop's control-variable
boolean quit
is never changed inside your loop, so exit condition of your loopquit == true
will never be reached. - the menu you're showing the user does not contain any option to quit
4 - QUIT
Summary: Once user enters a choice (1), the program gets stuck in a so called infinite-loop (3) always printing the current choice (2). Even after a restart the uninformed user has no chance to exit, since neither the menu does list this option (4), nor would choice = 4
have an effect since it's not in switch's cases (3).
Resolving Issues
- Modify the loop's control-variable inside the loop: set
quit = true
inside an additionalcase 4: quit = true; break;
- Make sure this only exiting branch will accessed by reading user's choice inside the loop: put
int choice = scanner.nextInt();
insidedo {}
and directly beforeswitch
. - Add an option to your menu so user knows how to exit (e.g.
4 - QUIT
), and use this option (see 1) - Show the menu inside the loop, directly before reading the user's choice.
Recommendations
Design the loop first: focus on exit!
- Use
while(exitCondition == false) {}
loops instead ofdo {} while(exitConfition == false)
because very importantexitCondition
is shown first (to every reader of your code), and it's controlling and avoiding an infinite-loop. So, rememeber setting it inside the loop! - Keep the code-lines inside your loop short, and modify control-variables on top, not inside nested blocks.
- When designing loops (especially for user-interaction), do it first, and use pseudo-code (see lines commented out below).
final static int QUIT_OPTION = 4;
public static void main(String[] args) {
int chosenOption = -1;
while (chosenOption != QUIT_OPTION) {
// showMenu();
// chosenOption = readUsersChoice();
// executeOption(chosenOption);
System.out.println("choosenOption: " = choosenOption); // for testing: see if choosenOption does change
choosenOption = QUIT_OPTION; // while design: simulates a single loop
}
}
The last 2 lines inside the loop are only for design-phase, where you will test a single loop (hence the final activating of QUIT_OPTION
). Put your focus on the control-variable: Is your user or program able to change it in desired way (hence the debugging println
)?
Divide and conquer: split task/logic into small separate functions
The loop above (inside main
) was the first small but main part of logic.
First task inside the loop: "displaying a menu"
private static void showMenu() {
System.out.println("Options - Main Menu");
System.out.println("1 - FIND");
System.out.println("2 - IN-SHUFFLE");
System.out.println("3 - OUT-SHUFFLE");
System.out.println("4 - QUIT");
System.out.println("Choose from above Options (1-4) by typing the number followed by RETURN:");
}
Try to keep this methods small, focused on one task. If possible keep them also isolated (from others). So you can test (call) them separately and check if the do what you want.
Next: "read the user's choice"
private static int readUsersChoice() {
Scanner scanner = new Scanner(System.in);
int choice = scanner.nextInt();
return choice;
}
This method needs special testing. Try what's happening if user enters a letter (e.g. Q
because wishing to quit). Did you catch the java.util.InputMismatchException
inside the method?
Finally the "choosen option will be evaluated and executed":
private static void executeOption(int choice) {
switch (choice) {
case 1:
System.out.println("\n1 - FIND\n");
//Deck.findTop();
break;
case 2:
System.out.println("\n2 - IN-SHUFFLE\n");
// call method
break;
case 3:
System.out.println("\n3 - OUT-SHUFFLE\n");
// call method
break;
default:
System.out.println("\nInvalid Option");
break;
}
}
Test it well, since here -based on an option- some other code/methods (even loops) could be called. You can also add the case: QUIT_OPTION
and print a Good-Bye.
回答4:
try this. You just have to move quit out of loop and bring in opions and userchoice into loop.
import java.util.Scanner;
public class Switchh {
static boolean quit = false;
public static void main(String[] args) {
int userChoice;
userChoice = menu();
}
private static int menu() {
Scanner scanner = new Scanner(System.in);
int choice;
do {
System.out.println("Choose an Option");
System.out.println("1 - FIND");
System.out.println("2 - IN-SHUFFLE");
System.out.println("3 - OUT-SHUFFLE");
choice = scanner.nextInt();
System.out.println("Choose an Option");
switch (choice) {
case 1:
System.out.println("\n1 - FIND\n");
//Deck.findTop();
break;
case 2:
System.out.println("\n2 - IN-SHUFFLE\n");
// call method
break;
case 3:
System.out.println("\n3 - OUT-SHUFFLE\n");
// call method
break;
default:
System.out.println("\nInvalid Option");
quit = true;
break;
}
}
while (!quit);
return choice;
}
}
来源:https://stackoverflow.com/questions/59411268/how-to-keep-switch-statement-continuing-in-java