So I'm building an email administration app and although it is working with if statements, I am trying to incorporate switch statements. I am prompting the user using a scanner to select which department they are from while building their email associated with it. Although when I am trying to return this.department, it is saying it is unreachable. I feel like I am missing something very obvious.
// Ask for the department
private String setDepartment() {
Scanner sc = new Scanner(System.in);
int department;
System.out.println("Select your department:\n1. Sales\n2.Accounting\n3.Development\n4.N/A");
department = sc.nextInt();
while (true) {
switch (department) {
case 1:
this.department = "Sales";
break;
case 2:
this.department = "Accounting";
break;
case 3:
this.department = "Development";
break;
case 4:
this.department = "";
break;
default:
System.out.println("Please choose a valid option (1-4)");
break;
}
sc.close();
}
return this.department; <-- Error: Unreachable code
}
problem is your condition inside the while() loop .It set always to true .So code below the while loop never gets executed .Try to have a different condition inside the while loop which terminates in a certain value.Otherwise you need place what ever you want to return inside the while loop.
Extra: Please also place your sc.close(); outside the while loop otherwise you can't use the resource after the first while loop iteration.so closing resource must be done always at the end.
Solution 1:
while(updatedTerminationCondition){//change the termination condition
}
Solution 2:
while(true){
//place your return value inside here but then loop will only run once
}
The problem is your switch-statement is in a while(true) loop that gets never exited. Unless you explicitly exit the loop e.g. by using break the program will never stop to execute the loop, meaning any code below it will never get reached, thats what the compiler is complaining about.
Related
But if I put it to "valid = false;" it does not work in debug or running.
In fact even running the code, I can't type anything after the "Do you want to order anything else?", no matter if it's in debug or running mode.
Am I missing something? After asking "how many you want to order" and you put in a number after it should ask "do you want to order anything else" which is does but then I can't type and break out of the do while loop. Everything else is working up to that point.
do {
boolean itemValid = true;
while (itemValid) {
System.out.println("Please enter an item name: ");
String enterItem = scnr.nextLine();
if (keepTrack.containsKey(enterItem)) {
System.out.println(keepTrack.get(enterItem));
itemValid = false;
} else {
System.out.println("Sorry we don't exist.");
continue;
}
System.out.println("How many do you want to order?");
int enterQuan = scnr.nextInt();
yourOrder = enterQuan;
valid = false;
}
System.out.println("Do you want to order anything else?");
String yesNo = scnr.nextLine();
if (yesNo.equalsIgnoreCase("n")) {
valid = false;
} else
break;
} while (valid);
Two problems with your code. First, probably unnoticed yet:
do ...
if (keepTrack.containsKey(enterItem)) {
System.out.println(keepTrack.get(enterItem));
itemValid = false;
} else {
System.out.println("Sorry we don't exist.");
continue;
}
When your input is "invalid", you turn into the else branch. The else branch continues the loop. The loop depends on value. Thus: as soon as you start with value=true, and then have an invalid input, you end up with a never-ending loop. Because nothing between the loop start and the continue statement will ever change the conditions that would end the loop.
Your actual question: when you call int enterQuan = scnr.nextInt() that does not consume the "ENTER" that you typed on the console. See here for details.
And there is another problem:
if (yesNo.equalsIgnoreCase("n")) {
valid = false;
} else
break;
}
When the user enters n or N, you go valid=false which ends the outer do-while loop. Thus: when the user enters anything else, the elsepath is taken. What is to be found in the else path? A break. Which also ends the do-while loop.
In other words: your code does exactly what you told it to do: to end the do-while loop, one way or the other.
The real answer is: you need to be much more careful what you put in your code. Each and any character matters. And when you put something into your code for an experiment: remember that it is there, and has effects.
Please let me describe the problem verbally first.
What you see on the console is what the problem is.
The coding is done with Scanner and switch-statement.
It asks to User, to who do you want to give MP portion. (each character's MP max is 30)
I wanted to test and tried 2,3,2,4 inputs to see what it would say, and as you could see, it says, "Jongwoo's MP is full. Choose different Character.." and so does for all other characters as expected, except for Kyungseok, who's MP is currently 15. So when I input 1 (for Kyungseok) it says Kyungseok's MP is healed , and all of sudden the rest character does the same thing. (please ignore the amount of it healed, I need to fix that)
One thing I realized was that they were printed in the order that I put in numbers to test : 2, 3, 2, 4.
So the input remained in the console became input and the switch-statement takes it as an input.
I don't know why it does that.
I have a lot of switch-statements, and it is not the only switch-statement having this problem. and the following code is the code for the switch-statement.
public static void chooseMMCha1(Character member) {
boolean wrongAnswer;
do {
wrongAnswer = false;
Scanner sc = new Scanner(System.in);
while(!sc.hasNextInt()) {
sc.next();
}
switch (sc.nextInt()) {
case 1:
chooseMMCha(chosenMember[0], member);
break;
case 2:
chooseMMCha(chosenMember[1], member);
break;
case 3:
chooseMMCha(chosenMember[2], member);
break;
case 4:
chooseMMCha(chosenMember[3], member);
break;
case 5:
chooseMMCha(chosenMember[4], member);
break;
case 6:
turn(member);
break;
default:
System.out.println("From 1 to 6");
wrongAnswer = true;
break;
}
}while(wrongAnswer);
}
It appears what you have here is unintended recursion.
In your chooseMMCha1() method you call chooseMMCha().
This method then checks to see if the selection is valid. If it isn't then it calls chooseMMCha1() again.
However once you input a valid input the call to chooseMMCha1() will come off the stack and it will return to your call to chooseMMCha(). Once it returns to here you print out that the character was healed. Thus once you input a valid input, all the invalid inputs that you pushed onto the stack will resolve and your method will print out that they have been healed.
In the case of an invalid input you need to put a return; statement after your call to chooseMMCha1() to make sure that you don't continue with the method once the invalid inputs come off the stack:
if(chosenMember.getMP() == chosenMember.getMaxMP()) {
System.out.println(chosenMember +"'s MP is already full");
chooseMMCha1(member);
return; //Exit the method
}
Here's a snip of my code:
while (true){
System.out.println("---Welcome to the Shape Machine---");
System.out.println("Available options:");
System.out.println("Circles");
System.out.println("Rectangles");
System.out.println("Triangles");
System.out.println("Exit");
//asks for selection
String option = console.next();
while (!option.equals("Cirlces") && !option.equals("Rectangles") && !option.equals("Triangles") && !option.equals("Exit")){
System.out.println("#ERROR Invalid option. Please try again.");
break;
}
switch (option) {
case "Circles": {
I have a menu set up and when the user inputs anything that isnt one of the options it's supposed to print out the error message and brings the user back into the menu. That works as intended, but if I put in a correct input the error message still prints out, but the switch statement runs as if there is no error and does the necessary calculations. I've tried using a while true loop within an if else statement and I still had the same problem. I also tried using an OR operator instead of an AND operator along with using a != instead of the !().equals method. I have no idea what to do to fix it. Any help would be very much appreciated.
I'm gonna go on a wild guess here and try to figure out what you were trying to accomplish.
Try this:
while (true){
System.out.println("---Welcome to the Shape Machine---");
System.out.println("Available options:");
System.out.println("Circles");
System.out.println("Rectangles");
System.out.println("Triangles");
System.out.println("Exit");
//asks for selection
String option = console.next();
switch (option) {
case "Circles":
//do something
break;
case "Rectangles":
break;
case "Triangles":
break;
case "Exit":
break;
default:
System.err.println("#ERROR Invalid option. Please try again.");
}
//now you can either put a flag or change the code to a DO..While
//depending on if you want to re-execute after each option..
}
If you want an if statement, you're gonna wanna do (to follow your version):
if (!option.equals("Cirlces") && !option.equals("Rectangles") && !option.equals("Triangles") && !option.equals("Exit")){
//print the error, then continue
}
or, easier to read
if( ! ( (option.equals("Circles") || option.equals("Rectangles") || option.equals("Triangles") || option.equals("Exit") ) ){
//print the error, then continue
}
Also please make sure that you're reading the right value, try printing it out and check.
If this doesn't work, there must be an error in the code you didn't provide, in that case please post a MCVE.
I'm trying to make a "choice" menu, where I am using a switch/case function to make the user choose. The problem in my code is that I want it to keep asking for input until the user types in "sair" which means "exit" in portuguese. When they type "ajuda" which means "help" they get a list of available commands to execute, but if the user types "ajuda" then the "sout" is executed and build is finished, the program ends there...
My goal is to make it run until we choose to stop, I think there was a ways using readln or similar.
Anyways, here's the chunk of code regarding to the choice:
public static String escolha() {
Scanner userInput = new Scanner(System.in);
String strEscolha = userInput.next();
boolean sair = false;
do {
switch (strEscolha) {
case "ajuda":
System.out.println("Comandos disponiveis:");
System.out.println("Ajuda; Fogo; Jogo; Resposta; Estado; Acaso; Reset; Sair;");
break;
case "Ajuda":
System.out.println("Comandos disponiveis:");
System.out.println("Ajuda; Fogo; Jogo; Resposta; Estado; Acaso; Reset; Sair;");
break;
case "sair":
System.out.println("Obrigado por jogar!");
sair = true;
break;
default:
System.out.println("Comando Invalido!");
continue;
}
} while (sair == false);
return null;
}
If anyone has a simple way to make it keep asking for commands, please let me know :(
Thanks in advance!!
PS: I just started, plese don't judge, my knowledge on java is neglectable :\
The main problem of your code is that you do not request user input in the 'ajuda' case.
Here is the code with some minor changes and some comments and recommendations:
// if your method isn't supposed to return anything, simply make it void
public static void escolha() {
Scanner userInput = new Scanner(System.in);
// print some useful information when the application starts, so that the user knows
// what to do
System.out.println("Comandos disponiveis:");
System.out
.println("Ajuda; Fogo; Jogo; Resposta; Estado; Acaso; Reset; Sair;");
String strEscolha = userInput.next();
boolean sair = false;
do {
// remove duplicate case by converting the input to lower letters
switch (strEscolha.toLowerCase()) {
case "ajuda":
System.out.println("Comandos disponiveis:");
System.out
.println("Ajuda; Fogo; Jogo; Resposta; Estado; Acaso; Reset; Sair;");
// read the user input
strEscolha = userInput.next();
System.out.println(strEscolha);
break;
case "sair":
System.out.println("Obrigado por jogar!");
sair = true;
break;
default:
System.out.println("Comando Invalido!");
}
} while (sair == false);
// do not forget to close the scanner, it might cause a memory leak
userInput.close();
}
Firstly, remove the System.exit, or you will shut down the entire JVM without executing the subsequent code (your IDE may have given you a dead code warning about this).
Secondly, you need to use sair == false (or, better, !sair) instead of sair = false. The former is a comparison; the latter is an assignment, making sair false.
do { ... } while (false) will execute the loop body once, but will not repeat.
Thirdly, the return strEscolha; immediately before while will cause the method to return before it attempts to loop, so it should be removed.
I am making a Text-Based Adventure game. In one room, I want to ask the player what to do, and if he goes through the door he/she moves to the next room. If he/she picks up the flashlight, the "what do you want to do?" question is repeated so they can go through the door after that. Here is my code:
case 1:
System.out.println("What do you want to do? Type 'door' to go through the door or 'flashlight' to pick up the flashlight.");
String roomOneAction = input.nextLine();
switch(roomOneAction) {
case "flashlight":
System.out.println("Picked up flashlight.");
//repeat what do you want to do? question
break;
case "door":
System.out.println("You open the door.");
//continue plot, don't repeat question
break;
default:
System.out.println("Error");
// repeat what do you want to do? question
break;
}
break;
With this code right now, it repeats the question for anything you type. I do not want this to happen if "door" is typed.
Also, how can I make it so that once the flashlight is picked up and the question is repeated, the flashlight can't be picked up a second time?
This might be close to what you want:
import java.util.Scanner;
public class Game {
private static boolean flashlightPicked = false;
private static boolean doorEntered = false;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (true) {
int x = 1;
switch (x) {
case 1:
System.out
.println("What do you want to do? Type 'door' to go through the door or 'flashlight' to pick up the flashlight.");
String roomOneAction = input.nextLine();
switch (roomOneAction) {
case "flashlight" :
if(!flashlightPicked){
System.out.println("Picked up flashlight.");
flashlightPicked = true;
} else {
System.out.println("Already picked up flashlight!");
}
// repeat what do you want to do? question
break;
case "door":
if(!doorEntered){
System.out.println("You open the door.");
doorEntered = true;
}else{
System.out.println("Already opened the door!");
}
// continue plot, don't repeat question
break;
default:
System.out.println("Error");
// repeat what do you want to do? question
break;
}
}
}
}
In this case you should probably store the information if you want to ask again or not:
boolean askAgain = true;
//...
case "door":
//...
askAgain = false;
//...
if (askAgain) {
System.out.println("...");
}
I would recommend using a while loop here. Can the player do anything else in the room or leave the room in a different way? If they can only leave the room using the 'door' command, set up the while loop to have the terminating factor being the 'door' command.
I don't like the idea of cascading multiple switches as you did. You should use state pattern and command pattern, but I assume you're a programming beginner, so I'll just try to answer your question.
Wrap the roomOneAction switch statement in a while loop, like
boolean foundFlashlight = false;
boolean askAgain = true;
while (askAgain)
{
// question + switch statement and so on
}
if the player picks the flashflight, set foundFlashlight to true.
In the next run, the player gets asked again. If he picks flashlight,
you have to evaluate the foundFlashlight variable, if the value is true,
tell the player he already has the flashlight and he should answer again.
In the door case, simply set askAgain to false. The loop while terminate then.
But again, this is not a nice, clean and easy to maintain approach. You should take a look at some design patterns. Especially the above mentioned state pattern.