Good morning everyone... I am wondering where to put the try-catch block for not integer Input(InputMismatchException) to work in this code,
If I put it here doesn't work, if I put it before while, it's an infinite loop, if you can explain where and why it will be perfect, thank you for your time.
public void additionalIngredients() {
Set<Integer> set = new HashSet<>();
boolean flag = false;
while (!flag) {
System.out.println("Enter your choice for extra toppings ");
int choices = scanner.nextInt();
scanner.nextLine();
try {
switch (choices) {
case 0:
System.out.println("Done");
flag = true;
break;
case 1:
if (!set.contains(choices)) {
double extraSauce = 1.2;
setAdditionalStuff(getAdditionalStuff() + extraSauce);
System.out.println("Extra sauce added on your pizza \n");
break;
} else {
System.out.println("You already added extra sauce, please consider to add something else");
break;
}
case 2:
if (!set.contains(choices)) {
double extraCheese = 2.3;
setAdditionalStuff(getAdditionalStuff() + extraCheese);
System.out.println("Extra cheese added on your pizza \n");
break;
} else {
System.out.println("You already added extra cheese, please consider to add something else");
break;
}
case 3:
if (!set.contains(choices)) {
double largeDough = 0.7;
setAdditionalStuff(getAdditionalStuff() + largeDough);
System.out.println("Your pizza has a large Dough \n");
break;
} else {
System.out.println("Your pizza has already a large dough, consider something else");
break;
}
}
set.add(choices);
} catch (InputMismatchException e) {
System.out.println("Please enter an integer!");
}
}
}
There are may ways to go about this. Always strive for solutions that make your code easier to read and understand.
One way to do that: you could for example create another helper method fetchSelectionFromUser() that does one thing only: loop (with try catch) until the user entered a valid number.
One guiding rule is the single layer of abstraction principle. And that tells you that having a-switch-in-a-try-in-a-loop isn't the way to go. As said, you could go for a loop that simply calls two methods: one that fetches the input, and another one that processes it.
Related
This question already has answers here:
How to read a single char from the console in Java (as the user types it)?
(7 answers)
Closed 3 years ago.
I'm a new programmer. I'm coding a user menu and I've a question on the do-while loop. When main() calls my first method containing my first loop it works as expected. However, when the user selects makes a choice and customerMenu() is called, it prints the menu 3 times. Why is this? Is there a mistake in my code?
public class Runner {
public static void main(String[] args) {
Menu m = new Menu ();
m.mainMenu();
}
}
public class Menu {
private char choice;
public void mainMenu () {
try {
do {
System.out.println("Create Order");
System.out.println("View Orders");
System.out.println("Customers");
System.out.println("Employees");
choice = (char) System.in.read();
} while (choice < '1' || choice > '4');
System.out.println("\n");
switch (choice) {
case '1':
System.out.println("Create Order page");
break;
case '2':
System.out.println("View Orders page");
break;
case '3':
customerMenu();
//System.out.println("Customers page");
break;
case '4':
System.out.println("Employees page");
break;
}
} catch (Exception e) {
System.out.println("Error");
}
}
// Do loop prints 3 times
public void customerMenu () {
try {
do {
System.out.println("Add a Customer");
System.out.println("Edit a Customer");
System.out.println("Delete a Customer");
choice = (char) System.in.read();
} while (choice < '1' || choice > '3');
System.out.println("\n");
switch (choice) {
case '1':
System.out.println("Add a Customer action");
break;
case '2':
System.out.println("Edit a Customer action");
break;
case '3':
System.out.println("Delete a Customer action");
break;
}
} catch (Exception e) {
System.out.println("Error");
}
}
}
There are no problems with the logic of your program but instead of using System.in.read () use either Scanner or BufferedReader. I can only guess that the three other characters that System.in.read () read are the null byte, line feed, and carriage return.
I just tried out the code (link to test env) and for me the menu is printing two times, not three.
The reason it prints twice is because System.in.read() reads in the next byte of data. When you type '3' and hit enter, that sends two bytes of data to the input stream. One byte for the 3 and one byte to indicate 'newline'.
The first time the do-while loop is entered, it reads in the 'newline' byte. That causes the loop to run a second time. The second time around, there's no more bytes to read so it waits for input for user.
Hi there i found your're mistake, i am not good with java. hmm maybe just printing the choice variable you will find your answer.
in mainmenu you have the choice variable and when you called customerMenu on the do while loop the choice variable is read again.
solution create another variable for customerMenu.
I need to create a decision tree using 'ifs' 'elses' and 'if else' if required.
i tried using only ifs but i couldn't get it to work properly. I've redone the beginning part using elses as well as ifs. I am getting an error that 'answer1' is not found. Can someone tell me if this is the correct start? I don't want to code the whole thing again and have to redo a lot of it because the results are not right.
Ive used only if statements but im thinking i have to use elses as well. if i were to include everything I've tried it would be well over 200 lines so ill keep it to this revised part I've started on.
import java.util.Scanner;
public class Guessing {
public static void main(String[]args) {
Scanner guess = new Scanner( System.in );
System.out.println("Think of something");
System.out.println("is it a living animal, plant, or non-living thing?");
String answer0;
answer0 = guess.nextLine();
answer0 = answer0.toUpperCase();
switch (answer0)
{
case "PLANT" : System.out.println("Is it a tree?");
break;
// case "LIVING : System.out.println("Does it have feathers, fur, or neither"); break;
// case "NON-LIVING" : System.out.println("Is it man-made?"); break;
// case "NON LIVING" : System.out.println("Is it man-made?");
default : System.out.println("Invalid");
}
if (answer0.equals("PLANT"))
{
System.out.println("Is it deciduous?");
String = answer1;
answer1 = guess.nextLine();
answer1 = answer1.toUpperCase();
switch (answer1)
{
case "YES" : System.out.println("Is it a fruit tree?");
break;
case "NO" : System.out.println("Is it native to North America?");
break;
default : System.out.println("Invalid");
}
}
if (answer1.equals("NO"))
{
System.out.println("Does it have an enclosed seed?");
String answerq3;
answerq3 = guess.nextLine();
answerq3 = answerq3.toUpperCase();
switch (answerq3)
{
case "YES" : System.out.println("Are you thinking of a cypress tree?");
break;
case "NO" : System.out.println("Are you thinking of a yew?");
break;
default : System.out.println("Invalid");
}
String answer4;
answer4 = guess.nextLine();
answer4 = answer4.toUpperCase();
switch (answer4)
{
case "YES" : System.out.println("Correct");
break;
case "NO" : System.out.println("Wrong");
break;
default : System.out.println("Invalid");
}
}
// if answer = tangerine tree
// system.out.print("Correct");
//}
// else {
// System.out.println("is it a banana tree");
//}
else
{
System.out.println("is it a weeping tree?");
}
else
{
System.out.println("Does it have flowers?");
}
}
}
its kind of hard to describe the expected results of a decision tree without going on and on and it getting confusing or being able to post a picture
So I think you're on the right track. If yes, this is what I ask next, if no ask some thing else. And you continue this again and again. If I understood you code correctly it looks good. So if yes, and than else if no, and else input is invalid. Try that, and Good Luck!
first question:
There is a do while loop, within the do section there is a switch. After selection case 1, some calculations are done, two options can result as shown in the If statement. My problem is code runs until the break; then just goes straight back to the menu loop. My question: how do i get the program to print the output for the user, then continue the menu loop?
Second question:
In case 1 there are two resulting options, the first being a failed response. from here, how do i get the program to loop back to the start of case 1 to ask for user input again? Even back to the main menu would be fine.
public static void showMenu() {
System.out.print('\u000c');
System.out.println("1 - Compute Change \n");
System.out.println("2 - Estimate Feast \n");
System.out.println("3 - \n");
System.out.println("4 - \n");
System.out.println("5 - I'm broke, get me out of here\n");
System.out.println("Select Option:\n");
}
public StackPost() {
System.out.println("Welcome to the Bank of Winterfell");
Scanner in = new Scanner(System.in);
do {
showMenu();
selection = in.nextInt();
switch (selection) {
case 1:
// get input, compute then decision:
if (something<somethingElse) {
// false response -
} else {
// correct response - system prints out some stuff back to user, back to main
// menu loop
}
break;
case 2:
break;
case 5:
System.out.println("\nEnding Now\n");
System.exit(0);
break;
default:
System.out.println("Instruction is invalid");
}
} while (selection != 5);
}
You could print "Press enter to continue" (or whatever you want to give notice of before locking the program), and add a call to Scanner#nextLine() before your break. This will lock the progression 'till user presses enter.
case 2:
// Some code here...
// Done, now show result and tell user to press any key to continue
System.out.println("Some fancy result from case handle code");
System.out.println("Press enter to continue...");
in.nextLine();
break;
You could add a while-loop that won't let the code continue 'till whatever input is expected in the first case is acceptable.
case 1:
System.out.println("Some handle that tells user to input something, and what is acceptable");
String input = null;
while(!(input = in.nextLine()).equals("something")) {
System.out.println("Wrong input, try again...");
}
// Input is acceptable, now do something with it...
System.out.println(input);
System.out.println("Press enter to continue...");
in.nextLine();
break;
Be aware, in your code, you call Scanner#nextInt(), and #nextInt doesn't consume the \n from pressing enter, and will thus be transferred into the switch case's usage of #nextLine(). You could avoid this with selection = Integer.parseInt(in.nextLine()).
You can use achieve it by:
For First question: Using return statement in case of correct response.
For Second question: Using while loop in case 1
After implementaing the proposed solution the StackPost() method will look like following. You can see the complete working code here:
public static void StackPost()
{
System.out.println("Welcome to the Bank of Winterfell");
try(Scanner in = new Scanner(System.in))
{
int selection;
do
{
showMenu();
selection = in.nextInt();
switch (selection)
{
case 1:
// get input, compute then decision:
while(true)
{
int something = in.nextInt();
int somethingElse = in.nextInt();
if (!(something<somethingElse)) {
// correct response - system prints out some stuff back to user, back to main
System.out.println("Print here the result");
// menu loop
return;
}
// false response - continue for next iteration in while-loop
}
//No need of 'break;' here
case 2:
break;
case 5:
System.out.println("\nEnding Now\n");
System.exit(0);
default:
System.out.println("Instruction is invalid");
}
} while (selection != 5);
}
}
Note: It is best practice to use try-with-resources while handling system resources which implements AutoCloseable interface.
I have an assignment for my Java class to program a Magic 8-ball. It is supposed to generate a random number for the response, contain a "while(true)" statement, and a switch statement for the replies. This is what I have so far. I can't seem to figure out how to work the "while(true)" statement in without it repeating infinitely.
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
String question;
int retry;
int q1;
System.out.print("What is your question for the Magic 8-bit 8-ball? ");
question = input.next();
System.out.print(process());
/*This is where I am having the problem. How do I work a "while(true)" in
* to where this won't infinitely repeat?
*/
}
public static int process() {
Random rand1 = new Random();
int random = rand1.nextInt(9);
int ans = random;
switch (ans) {
default: System.out.println("Does not compute!! Error! Error!");break;
case 1: System.out.println("The answer is.............. 42");break;
case 2: System.out.println("To get to the other side!!!");break;
case 3: System.out.println("Out of memory! Try again!");break;
case 4: System.out.println("Who do you think I am, IBM's Watson?");break;
case 5: System.out.println("Danger Will Robinson!! Danger!!");break;
case 6: System.out.println("What do you think?");break;
case 7: System.out.println("Fatal error.....nahhh just kidding");break;
case 8: System.out.println("Well, this is fun....NOT!");break;
case 9: System.out.println("Um...... 1,000,000,000,000,000,000,000?");break;
}
return ans;
}
}
Hum, the point of a while (true) loop is to be infinite, unless you add a break statement in it.
while (true) {
doStuff();
// if someCondition is true, this will exit the loop
if (someCondition)
break;
}
Note that this is equivalent to
do {
doStuff();
} while (!someCondition);
or
boolean someCondition = false;
while (!someCondition) {
doStuff();
}
It is usually preferrable to not have an infinite loop (while (true) for example) and have an explicit condition instead. Some exceptions exist, for example if the condition is complicated to express or if you want to break the loop at a particular position of the loop and not at the beginning or at the end :
while (true) {
doStuff();
if (someCondition)
break;
doSomeOtherStuff();
}
One of the many possible ways:
Create a a char and assign it to 'Y' (i.e. char continueLoop = 'Y').
Use this to control the while statement (i.e. while(char == 'Y') ).
Ask the user for input and process the input (i.e. System.out.println("Continue? Y/N") and then use Scanner to read the input and assign it to continueLoop.
You can create something similar using booleans.
So I'm currently dealing with this [keep in mind I cut most of the code out cause it's quite long]
int choice = 0;
while (choice != 7){
System.out.println("--- Mathematical Calculator ---");
System.out.println("");
System.out.println("Pick an operation from the list - Use nos. 1 to 7");
System.out.println("1) Multiplication");
System.out.println("2) Division");
System.out.println("3) Addition");
System.out.println("4) Subtraction");
System.out.println("5) Find the area of a regular object");
System.out.println("6) Find the volume of a regular object");
System.out.println("7) Exit Program");
**boolean ok = false;
do {
try{
choice = userInput.nextInt();
ok = true;
} catch (InputMismatchException e){
System.out.println("Invalid input");
}
}
while (ok = false);**
switch (choice) {
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
System.out.println("Thanks for using my program");
System.out.println("Program terminated");
break;
default: System.out.println("Invalid choice");
}
}
userInput.close();
}
So currently, when I run the program and enter something that is NOT an integer, the program will give the following output:
--- Mathematical Calculator ---
Pick an operation from the list - Use nos. 1 to 7
1) Multiplication
2) Division
3) Addition
4) Subtraction
5) Find the area of a regular object
6) Find the volume of a regular object
7) Exit Program
Invalid input
Invalid choice
Over
And over
And over
I know I've probably done something wrong with the exception handling (program works fine with valid input), but I really don't know how I can fix it.
Help?
You need to catch the \n\r with an userInput.nextLine() in your exception and it stops printing for ever like this
catch (InputMismatchException e){
System.out.println("Invalid input");
userInput.nextLine();
}
while (ok = false); should be while (ok == false);, or while (!ok);.
ok = false is an assignment.
Also, I guess you have intentionally left the cases empty, but even so, make sure that you put a break; on each of them, otherwise the option 7 will always be executed.
EDIT: for the infinite loop, you should also do what Kevin Esche suggests in his answer (+1).