Reset variables back to zero in do-while loop Java - java

I am working on an example using a do-while loop and switch statement. What I basically need is to accumulate numbers and depending on user input either add, substract, multiply or divide (mini calculator type).
The problem is when I ask the user to go back to the main menu the program does not reset the value as it is before the loop. The result is always the previous result.
Here is the code, it will explain it better.
import java.util.Scanner;
public class SwitchLoopNumbers{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int numbers=0;
int result=0;
int option;
boolean quit = true;
String done="";
do{
System.out.println("CALCULATOR MENU");
System.out.println("********** ****");
System.out.println("\n1. Add");
System.out.println("2. Substract");
System.out.println("3. Multiply");
System.out.println("4. Divide");
System.out.println();
System.out.print("Enter your option >> ");
option = scan.nextInt();
while(quit){
switch(option){
case 1:
System.out.print("Enter numbers, type 0 when done >> ");
numbers = scan.nextInt();
if(numbers==0)
quit=false;
result +=numbers;
break;
case 2:
System.out.print("Enter numbers, type 0 when done >> ");
numbers = scan.nextInt();
result -=numbers;
if(numbers==0)
quit=false;
break;
}
}
System.out.println("The total is: "+result);
System.out.println("Back to main menu ? y/n ");
scan.nextLine();
done = scan.nextLine();
//I did reset numbers and result here to zero but it did not work
}
while("y".equalsIgnoreCase(done));
System.out.println("Thank you for using calculator");
}
}

A couple things are going on here. To answer your question concisely, it's because you didn't reassign your variables before re-looping. Since you don't reassign result and quit, quit is false so it closes the loop, and result is unchanged so it then prints the same result. Try this:
System.out.println("The total is: "+result);
System.out.println("Back to main menu ? y/n ");
scan.nextLine();
done = scan.nextLine();
numbers = 0;
result = 0;
quit = true;
I think it's the most straight-forward solution to your problem.
EDIT: I also wanted to add that using quit as the while condition seems a little counter-intuitive. If I saw a condition quit that was true, my assumption would be that it would break the loop, not continue it. You might make your code a bit clearer by designating more meaningful variable names. So instead of saying something like:
boolean quit = true;
while(quit) {
//do stuff
if (some_condition) {
quit = false;
//close loop
}
}
This may be a little clearer:
boolean quit = false;
while(!quit) {
//do stuff
if (some_condition) {
quit = true;
//close loop
}
}
Just a general suggestion.

You can try to call main() again, but I'm not sure if it will work, solution can be make your own method eg. init() - where you will set vars into init state, and eg. work(), what will be remaining code :D
EDIT: you can make it this way
import java.util.Scanner;
public class main {
//if you want work with result after user will write "y" in the end
static int result = 0;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int numbers = 0;
int option;
boolean quit = false;
String done = "";
//int result = 0; // if you want also init result
// menu
System.out.println("CALCULATOR MENU");
System.out.println("********** ****\n");
System.out.println("1. Add");
System.out.println("2. Substract");
System.out.println("3. Multiply");
System.out.println("4. Divide");
// user menu input read
System.out.println();
System.out.print("Enter your option >> ");
option = scan.nextInt();
switch (option) {
case 1:
while (!quit) {
System.out.print("Enter numbers, type 0 when done >> ");
numbers = scan.nextInt();
if (numbers == 0) {
quit = true;
}
result += numbers; // result = result + numbers
}
break;
case 2:
while (!quit) {
System.out.print("Enter numbers, type 0 when done >> ");
numbers = scan.nextInt();
result -= numbers; // result = result - numbers
if (numbers == 0) {
quit = true;
}
}
break;
default:
System.out.println("Bad inpout");
break;
}
System.out.println("The total is: " + result);
System.out.println("Back to main menu ? y/n ");
scan.nextLine();
done = scan.nextLine();
//recursive call - run main() again
if (done.equals("y")) {
main(args);
} else {
System.out.println("Thank you for using calculator");
}
}
}

Related

Is there a way to loop input request until the user satisfies the condition in BigInteger?

I want to make a loop that repeat requesting for input until the user finally satisfies the condition of a number input instead of a string. By the way I'm using BufferedReader here. Is there a way to repeat it in BigInteger and BufferedReader?
mainLoop: while(true) {
System.out.println("Choose a number:");
System.out.println("1 - Addition");
System.out.println("2 - Subtraction");
System.out.println("3 - Multiplication");
System.out.println("4 - Division");
System.out.println("5 - QUIT");
try {
int choice = Integer.parseInt(myObj.readLine());
BigInteger Num1, Num2, sum, diff, qoutient, product;
String num1 = null, num2 = null;
switch (choice) {
case 1:
try {
num1 = myObj.readLine();
Num1 = new BigInteger(num1);
num2 = myObj.readLine();
Num2 = new BigInteger(num2);
sum = Num1.add(Num2);
System.out.println("The answer is "+sum);
} catch (NumberFormatException e){
}break;
The output actually returns to the main loop.
UPDATE:
actually I found out the answer. I did a while loop.
subLoop: while (true) {
try {
System.out.println("Enter 2 numbers");
num1 = myObj.readLine();
Num1 = new BigInteger(num1);
num2 = myObj.readLine();
Num2 = new BigInteger(num2);
sum = Num1.add(Num2);
System.out.println("The answer is "+sum+ "\n");
} catch (NumberFormatException e){
System.out.println("Use numbers only.");
continue subLoop;
}
break;
}
continue mainLoop;
What AxelH was suggesting is to keep code readable and traceable, you would want to say, for your main loop something like
boolean keepGoing = true;
while (keepGoing){
//main loop stuff here, and in the case where 5 is chosen, set keepGoing = false
}
Note no labels are needed. You may also want to set keepGoing false if your readLine fails (or signals you are at the end of the input).
I would suggest you introduce two simple functions to see if a given string is an integer:
public boolean isInteger( String input ) {
try {
Integer.parseInt( input );
return true;
}
catch( NumberFormatException e ) {
return false;
}
}
and
public boolean isBigInteger( String input ) {
try {
BigInteger t = new BigInteger( input );
return true;
}
catch( NumberFormatException e ) {
return false;
}
}
I am not quite familiar enough with the logic of how your input works, so I don't know if you want to loop until you get a good choice, first, and then worry about the input numbers after.
If so, the getting a good choice loop looks like
boolean needAGoodChoice = true;
int choice = 0;
while (needAGoodChoice){
String numChoice = myObj.ReadLine();
if (isInteger(numChoice)){
choice = Integer.parseInt(numChoice);
//could add check here the number is between 1 and 5 inclusive
needAGoodChoice=false;
}
else{
System.out.println("Use numbers only for choice.");
}
}
and when that while concludes, choice has the number of the choice.
The same logic would apply to getting values into your Num1 and Num2 BigIntegers via the num1 and num2 Strings.
boolean needNums = true;
while (needNums){
System.out.println("Enter 2 numbers");
num1 = myObj.ReadLine();
num2 = myObj.ReadLine();
if (isBigInteger(num1) and isBigInteger(num2)){
Num1 = new BigInteger(num1);
Num2 = new BigInteger(num2);
needNums=false;
}
else{
System.out.println("Use numbers only for operations.");
}
}
Since all your operations are binary, I think I'd put this getting the numbers loop outside the switch statement (inside an if block that checks choice>=1 and choice<=4) to avoid repeating it 4 times.
Substantively it's not so dramatically different from your solution and looks verbose, but I think in the long run it will be easier to maintain and follow.

program terminate after using try catch block in switch statement

the following code terminate after try catch block catches exception.its not allowing me to make choice from the menu option. so my question is what changes do i have to make on this code so that i can loop back so that i can get user input again.
public class Main {
public static void main(String[] args) {
Modify modifyObj = new Modify();
int choice = 0 ;
Scanner input = new Scanner(System.in);
//begin loop
do {
try{
//display menu
System.out.println("Choose one option from following option available: ");
System.out.println("0) Exit program. ");
System.out.println("1) Create a Roster");
System.out.println("2) Modify a Roster");
System.out.println("3) Delete a Roster");
choice = input.nextInt(); //gets user input
switch (choice) {
case 1:
//code
break;
case 2:
//code
break;
case 3:
//code
break;
}// end of switch statement
break;
}//end oftry
catch(InputMismatchException inputMismatchException){
System.out.println("Enter integer value between 0 and 7:");
continue;
}
}while (choice!=0); //loop until user exit 0.
}//end of main
}// end of Main class
Make sure choice isn't 0 before you continue;
catch(InputMismatchException inputMismatchException){
System.out.println("Enter integer value between 0 and 7:");
choice = 1; // <-- not 0.
continue;
}
Note that you default choice to an initial value of 0.
You Could Use Methods
If you extracted your logic into one (or two) utility methods to display the menu and get the user's choice it would simplify things; something like
private static void showMenu() {
System.out.println("Choose one option from following option available: ");
System.out.println("0) Exit program. ");
System.out.println("1) Create a Roster");
System.out.println("2) Modify a Roster");
System.out.println("3) Delete a Roster");
}
private static int getUserOption(Scanner input) {
while (true) {
showMenu();
if (input.hasNextInt()) {
int t = input.nextInt();
switch(t) {
case 0: case 1: case 2: case 3:
return t;
}
} else {
input.nextLine();
}
}
}
Then your main could invoke it like
public static void main(String[] args) {
Modify modifyObj = new Modify();
Scanner input = new Scanner(System.in);
int choice;
// begin loop
do {
choice = getUserOption(input);
if (choice != 0) {
System.out.printf("You chose %d.%n", choice);
}
} while (choice != 0); // loop until user enters 0.
}// end of main

For loop printing twice sometimes

In my convertEuro method the for loop is causing the output to be printed twice, but only sometimes. What I mean is this is what gets displayed:
Converting values to Euros.
£4.00 >>> €5.45
£123.44 >>> €168.13
Converting values to Euros.
£4.00 >>> €5.45
£123.44 >>> €168.13
During testing it seems to do this maybe 2 times out of 10, and I can't figure out why. Code below if someone can please help:
import java.util.Scanner;
import java.text.DecimalFormat;
import java.util.ArrayList;
public class Conversion {
public void mainMenu(Scanner scan, ArrayList<Double> values, DecimalFormat twoDecimal) {
int menuChoice;
System.out.println("1. Enter values and type -1 to stop");
System.out.println("2. Euros");
System.out.println("3. Dollars");
System.out.println("4. Yen");
System.out.println("5. Rupees");
System.out.println("6. Exit");
menuChoice = scan.nextInt();
switch (menuChoice) {
case 1:
enterValues(scan, values, twoDecimal);
case 2:
scan.nextLine();
convertEuro(scan, values, twoDecimal);
}
}
public void enterValues(Scanner scan, ArrayList<Double> values, DecimalFormat twoDecimal) {
double value = 0;
do {
System.out.print("Enter value. Enter -1 to stop: £");
while (!scan.hasNextDouble()) {
System.out.print("Please enter a double (£xx.xx): £");
scan.nextLine(); //Consumes \n
scan.next();
}
value = scan.nextDouble();
if (value != -1) {
values.add(value);
System.out.println("Value entered.");
}
}
while (value != -1);
System.out.println("Returning to main menu. ");
mainMenu(scan, values, twoDecimal);
}
public void convertEuro(Scanner scan, ArrayList<Double> values, DecimalFormat twoDecimal) {
System.out.println("Converting values to Euros.");
for (int i = 0; i < values.size(); i++) {
System.out.println("£" + twoDecimal.format(values.get(i)) + " >>> " + "\u20ac" + twoDecimal.format(values.get(i) * 1.362));
}
}
public static void main(String[] args) {
Conversion conv = new Conversion();
Scanner scan = new Scanner(System.in);
ArrayList<Double> values = new ArrayList<Double>();
DecimalFormat twoDecimal = new DecimalFormat("0.00");
conv.mainMenu(scan, values, twoDecimal);
scan.close();
}
}
You need to add a break; statement:
case 1:
enterValues(scan, values, twoDecimal);
break;
When the switch statement hits the correct case, it executes it and proceeds executing other cases which are below until and unless it hit an break statement.
The correct process is
switch (menuChoice) {
case 1:
enterValues(scan, values, twoDecimal);
break;
case 2:
scan.nextLine();
convertEuro(scan, values, twoDecimal);
break;
}
Thats why best practice is to put break statement after every case end.
Thank you

Validate Scanner input on a numeric range

I'm currently creating my first game which is executed in a console.
I've been asked to validate an input which can be done with a simple code. The goal is to input, and then validate if that number is an integer, and is on a range of 1-4. If possible, the problem should be solved with basic algorithm.
The problem is that it won't give me the result I wanted. It works when I enter a string, but it loops on every number I put including the number in the range. Does anyone know why?
public class Menu {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
int input = 0;
int min = 1;
int max = 4;
boolean inputValidate;
System.out.println("Main Menu");
System.out.println("=========");
System.out.println("1. Play Game");
System.out.println("2. About");
System.out.println("3. View Saved Games");
System.out.println("4. Exit");
System.out.println("");
do {
System.out.print(">> ");
if (!scanner.hasNextInt()) {
inputValidate = false;
System.out.println("Not a number. Please input number 1-4.");
scanner.nextLine();
} else if (input <= max && !(input < min)) // if input <= 4 and input is not less than 1
{
input = scanner.nextInt();
inputValidate = true;
} else {
inputValidate = false;
System.out.println("Not in range. Please input number 1-4.");
scanner.nextLine();
}
} while (!(inputValidate));
switch (input) {
case 1:
break;
case 2:
System.out.println("Good work!");
break;
case 3:
break;
case 4:
break;
}
}
}
}
Because you instantiate input to be 0, but never give the user an opportunity to change this, the conditions for the first two conditionals are always false (nothing is read from the Scanner and 0 is not between min and max). Therefore, the program falls through to the else every time. Just add a statement before the do-while that will obtain a value for input from the user.
input = scanner.nextInt();
// your do-while loop
(You'll also probably have to adjust the code slightly to get the type of interaction you're looking for. Hint - you're reading two values from the user.)
As Clint said the problem was in your input. Here's a demo how you can fix this,
try (Scanner scanner = new Scanner(System.in)) {
int input = 0;
int min = 1;
int max = 4;
boolean inputValidate = false;
System.out.println("Main Menu");
System.out.println("=========");
System.out.println("1. Play Game");
System.out.println("2. About");
System.out.println("3. View Saved Games");
System.out.println("4. Exit");
System.out.println("");
do {
System.out.print(">> ");
try {
input = scanner.nextInt();
if (input >= min && input <= max) {
inputValidate = true;
} else {
System.out
.println("Not in range. Please input number 1-4.");
scanner.nextLine();
}
} catch (InputMismatchException exception) {
System.out
.println("Not a number. Please input number 1-4.");
scanner.nextLine();
}
} while (!(inputValidate));

How would I create a "infinite" loops until the user decides to call it quits?

I'm having a slight problem.
I have a menu asking to:
reroll
get val
show max
show min
when the user chooses an option I want it to do one of them THEN re ask the menu in a sort of inifinite loop:
code:
import java.io.InputStream;
import java.util.Scanner;
class RecordDice {
public static void main(String[] args){
int dSides, Sides, Choice;
int max, min;
Scanner s = new Scanner(System.in);
Scanner c = new Scanner(System.in);
System.out.println("How many sides should the dice have?");
Sides = s.nextInt();
if(Sides == 4 || Sides == 6 || Sides == 12 || Sides == 20 || Sides == 100){
System.out.println("Please make a choice:\n" +
"1 - reroll the dice\n" +
"2 - get the value\n" +
"3 - show the maximum\n" +
"4 - show the minimum");
} else {
System.exit(-1);
}
Dice2 d = new Dice2(Sides);
int Choice = c.nextInt();
int Value = d.getValue();
switch(Choice){
case 1:
System.out.println();
d.reroll();
break;
case 2:
System.out.println("The current value is " + Value);
break;
case 3:
System.out.println("The maximum is " );
break;
case 4:
System.out.println("The minimun is ");
break;
}
}
}
Would putting the menu in a method and just calling the method every time a option is picked?
You can use a while loop to keep displaying it.
boolean keepGoing = true;
While(keepGoing)
{
//your code
}
Then to end it ask the user if they want to end it an set the boolean to false.
Add "5 - quit" to your menu.
Create a boolean, something like exit, initialized to false.
Add case 5: exit = true; break;
Then wrap the whole thing in while(!exit)
boolean exit = false;
while(!exit) {
//all the code you already have, starting with:
System.out.println("How many sides should the dice have?");
//and ending with the switch statement
//Plus the addition to the menu and addition to the switch statement
}
Ordinarily, I would do something like:
while(true) {
//do stuff
if(someExitCondition) {
break;
}
}
But seeing how as you're handling your user input with a switch statement, my above suggested method seems to be the cleanest way of handling it in this scenario.
Wrap it all in a do-while loop.
boolean userWantsToQuit = false;
do {
// code
// evaluate userWantsToQuit…
} while (!userWantsToQuit);
boolean keepGoing=true;
while(keepGoing)
{
//user input
if(user input to exit)
{
keepGoing=false;
}
}
or
while(true)
{
//user input
if(user input to exit)
{
break;
}
}
Assuming selection of dice sides you will allow only once, put code below that in do while loop.
You may prompt user "Do you wish to continue" after your switch block.
Get that value scanned
Condition in while loop will be something list while("YES".equals(userInput)).. assuming user will input YES or NO strings.

Categories