Reputation: 23
Why does the code break when the default case of the switch function is used.
import java.util.Scanner;
public class Main {
static void checkCommand(String command)
{
switch (command) {
case "add" -> System.out.println("added");
case "access" -> System.out.println("accessed");
case "compare" -> System.out.println("compared");
default -> {
System.out.println("Invalid command, please try again");
enterCommand();
}
}
}
static void enterCommand(){
System.out.print(">>> ");
Scanner usrInput = new Scanner(System.in);
String input = usrInput.nextLine();
while (!input.equals("quit")){
checkCommand(input);
System.out.print(">>> ");
input = usrInput.nextLine();
}
}
public static void main(String[] args) {
enterCommand();
}
}
When I enter in "add", "compare", or "access", and then "quit", the program works as intended, but if I enter in anything that is incorrect where it uses the default case, the program breaks and repeatedly asks for input even if the input is "quit". I have tried a few different things to fix it and nothing has worked. I'm trying to keep the switch statement but if there isn't a way to keep it and have the program run as intended I am open to other options.
Upvotes: 0
Views: 419
Reputation: 679
You need to understand the recursive mechanism. When the latest recursive has done, it needs to do the remaining tasks from previous recursive. I added comments into your code to explain:
static void checkCommand(String command){
switch (command) {
// ...
default: {
System.out.println("Invalid command, please try again");
enterCommand(); // recursive is calling here.
}
}
}
static void enterCommand(){
System.out.print(">>> ");
Scanner usrInput = new Scanner(System.in);
String input = usrInput.nextLine(); // time 1: input: test | time 2: input: quit -> done recursive 1.
while (!input.equals("quit")){
checkCommand(input); // time 1: go to default and call recursive, go to input time 2
System.out.print(">>> "); // Do the remaining task from time 1. In case you input time 3: "quit". the program will exit.
input = usrInput.nextLine();
}
}
The more recursives are called, the more remain tasks need to do. In your code, to quit the program, you need to type "quit" (n + 1) times if the recursive is called n times
Solutions: To quit immediately after typing "quit" in the first time, just remove the recursive call.
default: {
System.out.println("Invalid command, please try again");
}
Upvotes: 3
Reputation: 20914
Your code works for me. The only problem is that I have to enter quit twice, after entering an invalid command, in order for the program to terminate.
Here is output from a sample run of the exact same code as in your question:
>>> access
accessed
>>> add
added
>>> george
Invalid command, please try again
>>> compare
compared
>>> quit
>>> quit
I am required to enter quit twice because method enterCommand
is being called from method checkCommand
. You don't need to do this. The while
loop, in method enterCommand
will ensure that the user is prompted again to enter a command – even after [s]he has entered an invalid command.
Calling enterCommand
from checkCommand
means that you are essentially calling enterCommand
recursively. In the above output, I needed to enter quit twice, since I only entered a single, invalid command. I suggest that you run your code in a debugger to understand why you get this behavior.
As @OldDogProgrammer wrote in his comment to your question, you should create a Scanner
object only once rather than each time method enterCommand
executes.
As @MadProgrammer wrote in his comment, a do-while
loop may be more appropriate than a plain while
loop.
Also, quit is not an invalid command so I think that you need to handle that command in method checkCommand
and the handling is that you just ignore the command. Since you are using switch expressions, I couldn't find a way to "ignore" a case so in the below code I simply print an empty string. Alternatively, you could print an appropriate message such as Good bye, for example.
import java.util.Scanner;
public class Main {
private static Scanner usrInput;
static void checkCommand(String command) {
switch (command) {
case "add" -> System.out.println("added");
case "access" -> System.out.println("accessed");
case "compare" -> System.out.println("compared");
case "quit" -> System.out.print("");
default -> {
System.out.println("Invalid command, please try again");
}
}
}
static void enterCommand() {
String input;
do {
System.out.print(">>> ");
input = usrInput.nextLine();
checkCommand(input);
} while (!input.equals("quit"));
}
public static void main(String[] args) {
usrInput = new Scanner(System.in);
enterCommand();
}
}
Here is the output when I ran the above code:
>>> access
accessed
>>> add
added
>>> George
Invalid command, please try again
>>> compare
compared
>>> quit
As you can see, I only need to enter quit once.
Upvotes: 3