Trouble trying to restart my Java program - java

After looking up numerous ways to restart a Java program within itself, a while loop seemed like the easiest option. Here's an example of a basic calculator program I'm trying this with:
import java.util.Scanner;
class a {
public static void main(String args[]){
boolean done = false;
int oper;
Scanner input = new Scanner(System.in);
System.out.println("McMackins Calc v2.0 (Now with fewer crashes!)");
while (!done)
{
System.out.println("What operation? (0 for quit, 1 for add, 2 for subtract, 3 for multiply, 4 for divide, 5 for divide with remainder, 6 for average, 7 for account interest):");
while (!input.hasNextInt()){
System.out.println("Enter a valid integer.");
input.next();
}
oper = input.nextInt();
switch (oper){
case 0:
done = true;
break;
case 1:
add addObject = new add();
addObject.getSum();
break;
case 2:
sub subObject = new sub();
subObject.getDifference();
break;
case 3:
times multObject = new times();
multObject.getProduct();
break;
case 4:
divide divObject = new divide();
divObject.getQuotient();
break;
case 5:
remain remObject = new remain();
remObject.getRemainder();
break;
case 6:
avg avgObject = new avg();
avgObject.getAvg();
break;
case 7:
interest intObject = new interest();
intObject.getInterest();
break;
default:
System.out.println("Invalid entry.");
break;
}
}
input.close();
}
}
However, this seems to throw out a NoSuchElementException at the end of the first time through the loop, and crashes the program. The function of this class is to take the initial input from the user to determine which class to use, which will determine which mathematical operation to perform. Everything works fine without the while (!done) loop.
Example usage:
McMackins Calc v2.0 (Now with fewer crashes!)
What operation? (0 for quit, 1 for add, 2 for subtract, 3 for multiply, 4 for divide, 5 for divide with remainder, 6 for average, 7 for account interest):
1
How many addends?
1
Enter your numbers now.
1
You have entered 1 addend.
The sum is: 1.0
What operation? (0 for quit, 1 for add, 2 for subtract, 3 for multiply, 4 for divide, 5 for divide with remainder, 6 for average, 7 for account interest):
Enter a valid integer.
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at a.main(a.java:13)
I've also tried just having the other classes refer back to this one, but since main is a static method, I cannot access it the way I intended.
Note that I'm a bit of a beginner at Java, which is why my program is pretty simple, so try to keep it simple if it can be, or post code and then in DETAIL explain what it means so I can not only fix this problem, but future ones as well.
Thank you!
EDIT:
The code is formatted better within my editor. The braces came out in odd positions when I posted it here.
Since apparently a is written correctly, this is my add class. Hopefully this will clear something up.
import java.util.Scanner;
public class add {
public void getSum(){
Scanner input = new Scanner(System.in);
double total, addend;
int entries, count;
total = 0;
count = 0;
System.out.println("How many addends?");
while (!input.hasNextInt()){
System.out.println("Enter a valid integer.");
input.next();
}
entries = input.nextInt();
System.out.println("Enter your numbers now.");
while (count < entries){
while (!input.hasNextDouble()){
System.out.println("Enter a valid number.");
input.next();
}
addend = input.nextDouble();
total = total + addend;
count++;
if (count == 1){
System.out.println("You have entered " + count + " addend.");
}else if (count > entries){
System.out.println("You have entered too many addends! Contact program developer.");
}else{
System.out.println("You have entered " + count + " addends.");
}
}
System.out.println("The sum is: " + total);
input.close();
}
}

public static void main(String args[]){
boolean done = false;
int oper;
Scanner input = new Scanner(System.in);
System.out.println("McMackins Calc v2.0 (Now with fewer crashes!)");
while (!done) {
System.out.println("What operation? (0 for quit, 1 for add, 2 for subtract, 3 for multiply, 4 for divide, 5 for divide with remainder, 6 for average, 7 for account interest):");
while (!input.hasNextInt()){
System.out.println("Enter a valid integer.");
input.next();
}
oper = input.nextInt();
switch (oper){
case 0:
done = true;
break;
case 1:
System.out.println("1");
break;
case 2:
System.out.println("2");
break;
case 3:
System.out.println("3");
break;
case 4:
System.out.println("4");
break;
case 5:
System.out.println("5");
break;
case 6:
System.out.println("6");
break;
case 7:
System.out.println("7");
break;
default:
System.out.println("Invalid entry.");
break;
}
}
input.close();
}
This seemed to work for me so perhaps the error is something to do with your own classes (add, divide) etc.
Also, it's best to keep with convention when creating your own classes by capitalizing the first letter e.g. "add" should be "Add".
You could probably make this a little bit easier to read by building a general "Operations" class which holds an add method, a subtract method etc.
EDIT:
try this for your add method:
public static int add() {
Scanner s = new Scanner(System.in);
int counter = 0;
System.out.println("How many numbers to add?");
int numCount = s.nextInt();
for(int i = 0; i < numCount; i++) {
System.out.println("enter number");
counter += s.nextInt();
}
return counter;
}

Use bufferedreader and inputstream instead of Scanner class. This class creates a lot of bugs and errors, since sometimes it takes more arguments, that you expect it to take.
Also:
while (!input.hasNextInt()){
System.out.println("Enter a valid integer.");
input.next();
}
Your using hasNextInt method wrong, instead of it try to make simple while loop with Boolean and input.next() should be replaced with input.nextLine().
Another thing, you should check,if user typed integer instead of string or something in the while loop and it range. If everything is okay, you should change Boolean value to true and make him go out of the while loop.

For future users who are wondering how to fix this issue, through some reprogramming, I discovered that my problem was closing the input variable BEFORE the end of the loop. By having the program restart indefinitely and only close input when done, this program works fine.
Thanks to Benjamin's response, I am currently in the process of cleaning up and shortening my code by way of for loops.

Related

do while loop with a Yes/No user prompt

Im having issues with my code. The code is to find a factorial of a number, then ask if you want to run the program again, its suppose to run again then exit. However, when I enter Y to restart the program it breaks and wont restart and when I enter N to exit it wont exit the program.
private static Object Cont;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Greetings
System.out.println("Welcome to my factorial program! ");
System.out.println("Please choose from the following: ");
//Menu
System.out.println("1. Run Program");
System.out.println("2. Exit Program");
int choice = scanner.nextInt();
switch (choice) {
case 1:
System.out.println("This program will determine the factorial value of positive integers.");
do {
System.out.println("The starting number is 1.");
System.out.println("Please enter an ending integer value:");
int n = scanner.nextInt();
for (int i = 1; i <= n; i++) {
System.out.println(i + "! = " + fact(i));//call to function
}
System.out.println("Run factorial program again? (Y for Yes, N for No): ");
String Cont = scanner.next();
if (Cont.equals("N")) {
break;
}
} while (Cont.equals("Y"));// do while loop
break;
//Menu Exit
case 2:
System.out.println("Thank you for using the program.");
System.out.println("Goodbye");
default:
System.exit(1); // remebered from last week to set this to one
System.out.println("Goodbye");
break;
}
}//Factorial Math
static long fact(int x) {
long f = 1;
for (int i = 1; i <= x; i++) {
f = f * i;
}
return f;
} //End Main Method
What am I missing or doing wrong?
You have a couple of problems here.
The first problem is that you have declared two distinct Cont variables. The first one is a static field. The second one is a local variable that is declared in the body of the loop.
I don't know why you declared the static field, but I imagine you did it because the } while (Cont.equals("Y")); didn't compile without it. (That is because the Cont variable declared in the loop is not in scope outside of the loop's body.) Unfortunately, it was not the correct solution. Because, you now have code that is assigning to one variable and tests a different one. Naturally, that doesn't work.
To my mind, the correct solution is to get rid of the static field, and the declaration in the loop body. Than add a declaration for Cont before the start of the loop. (It shouldn't have an initialization). Finally, in the loop you just need to read (using the scanner) and assign a string to Cont so that you can test in the loop condition.
The second problem is that you have a redundant test in there. If you are going to test to see if you need to continue using } while (Cont.equals("Y")); you don't also need to test if Cont is "N" and break.
Relatedly, equals("Y") is not the same as not equals("N"). (Consider "Hello" ... or "n". They are neither "Y" or "N".) So if you really want to stop the loop when the user types N, then the loop termination condition should be:
} while (!Cont.equals("N")); // keep looping while not 'N'
Finally there are a couple of significant style-related issues.
Declaring a static field is usually a mistake.
It is a mistake to use a field when you should be using a local variable. State that is only relevant to a single execution of a method should be1 represented using a local variable.
It is a major stylistic error for a variable to start with an uppercase letter. Cont should be cont.
If you ever work in a professional Java development team that pays attention to style, you will get a hard time for ignoring Java identifiers conventions. And (IMO) your teacher should dock style marks for this mistake.
1 - Reasons: 1) It makes the method harder to read because the variable declaration is further away from its use. 2) It typically makes the code non-reentrant. 3) It opens you up to unwanted coupling between methods; e.g. if two methods accidentally share the same "local variable declared as a field". 4) In many cases it uses more memory.
You need an additional break and declare Cont before the do loop:
//private static Object Cont; This is is not declared on the right location, we'll declare it later
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Greetings
System.out.println("Welcome to my factorial program! ");
System.out.println("Please choose from the following: ");
//Menu
System.out.println("1. Run Program");
System.out.println("2. Exit Program");
int choice = scanner.nextInt();
switch (choice) {
case 1:
System.out.println("This program will determine the factorial value of positive integers.");
String Cont = null; // Cont must be declared here
do {
System.out.println("The starting number is 1.");
System.out.println("Please enter an ending integer value:");
int n = scanner.nextInt();
for (int i = 1; i <= n; i++) {
System.out.println(i + "! = " + fact(i));//call to function
}
System.out.println("Run factorial program again? (Y for Yes, N for No): ");
Cont = scanner.next();
if (Cont.equals("N")) {
break;
}
} while (Cont.equals("Y"));// do while loop
break;
//Menu Exit
case 2:
System.out.println("Thank you for using the program.");
System.out.println("Goodbye");
break; // requires this additional break
default:
System.exit(1); // remembered from last week to set this to one
System.out.println("Goodbye");
break;
}
}//Factorial Math
static long fact(int x) {
long f = 1;
for (int i = 1; i <= x; i++) {
f = f * i;
}
return f;
} //End Main Method

How to fix loop while/try catch error in java

I am working on creating a simple calculator program (first week into this java programming).
problem background: only 5 options are valid. (1-add; 2- subtract; 3- multiple;4. divide; and 5.exit). when users enter 1-4 options, results will populate but users need to loop back to reenter data till option 5 is selected. 5 is to exit the program(the only way to end the loop/program). my questions: 1. how to stop try-catch from running nonstop? is there a better way to implement try-catch? e.g., handling string data error messages.Ideally, if a string is entered, the code should loop back to restart again by producing the message "please reenter the number..." until a valid number is entered by users 2. I am trying to use as many static methods as possible in the main class. i am not sure whether the way I did was accurate?
Here is the code I input:
12 2
//-everything works well.
2 //-enter again
s s (string entry-error)
then, the below message populates:
"You have entered invalid floats. please re-enter:
Exception in thread "main" java.util.InputMismatchException
...
at calculator.performSubtract(calculator.java:65)
at calculator.main(calculator.java:34)"
code(sample)
public class calculator {
//use static methods to implement the program
static Scanner userInput = new Scanner(System.in);
static int userChoice;
static float numberOne;
static float numberTwo;
static float answer;
static int choice;
public static void main(String[] args) {
do {
//this menu statement has to be repeated unless 5 is entered (exit the
//program)
System.out.println("Welcome to <dj's> Handy Calculator\n\n\t \1. Addition \n\t 2. Subtraction\n\t 3. Multiplication\n\t 4. Division\n\t 5. Exit\n\n");
System.out.print("What would you like to do? ");
try {
choice = userInput.nextInt();
}catch (InputMismatchException e) {
continue;
}
switch (choice) {
case 2: performSubtract();
break;
...
case 5: exit();
break;
}
}while(choice >0 && choice <5);
userInput.close();
}
public static void performSubtract () {
//catch error statement.
try {
numberOne = userInput.nextFloat();
numberTwo= userInput.nextFloat();
answer= numberOne-numberTwo;
} catch (Exception e) {
System.out.println("You have entered invalid floats. please re-enter: ");
numberOne = userInput.nextFloat();
numberTwo= userInput.nextFloat();
}
System.out.printf("Please enter two floats to subtraction, separated by a space: %.1f %.1f\n", numberOne, numberTwo);
System.out.printf("Result of subtraction %.1f and %.1f is %.1f\n", numberOne, numberOne, answer);
System.out.println("\nPress enter key to continue...");
}
}
I believe the issue is that you are not clearing the problem token from the scanner.
Your catch statement prints an error message, and then goes around to try and parse the same token into an int or float again.
You might check here: https://www.geeksforgeeks.org/scanner-nextint-method-in-java-with-examples/
It looks like you need to call userInput.next() to advance past the invalid token.
Also, hasNextInt() will let you avoid the catch altogether if you prefer.
Your error lies in the fact that Scanner.nextFloat, when reading an invalid input, does not advance the current token. This means that when you call nextFloat twice again in the catch statement, you once again read the tokens s and s, the first of which will cause an InputMismatchException to be thrown once again. You should change your performSubtract method to look something like this:
public static void performSubtract () {
//catch errors
System.out.println("Please enter two floats to subtraction, separated by a space");
userInput.nextLine();//ignore the new line
do {
try {
String[] nextLineTokens = userInput.nextLine().split("\\s+");
if(nextLineTokens.length != 2)
{
System.out.println("You have not entered two floats. please re-enter:");
continue;
}
numberOne = Float.parseFloat(nextLineTokens[0]);
numberTwo = Float.parseFloat(nextLineTokens[1]);
answer= numberOne-numberTwo;
break;
}
catch (Exception e) {
System.out.println("You have entered invalid floats. please re-enter: ");
}
} while (true);
System.out.printf("You entered: %.1f %.1f\n", numberOne, numberTwo);
System.out.printf("Result of subtraction %.1f minus %.1f is %.1f\n", numberOne, numberTwo, answer);
System.out.println("\nPress enter key to continue...");
userInput.nextLine();
}
Additionally, your parsing code continues if you enter an invalid input, but exits if you type in a number that is not 1-5. If it is the first time that you read in input, the code exits for invalid inputs as well. You should probably change your parse iteration loop as so:
public static void main(String[] args) {
while(choice != 5) {
//this menu statement has to be repeated unless 5 is entered (exit the
//program)
System.out.println("Welcome to <dj's> Handy Calculator\n\n\t 1. Addition \n\t 2. Subtraction\n\t 3. Multiplication\n\t 4. Division\n\t 5. Exit\n\n");
System.out.print("What would you like to do? ");
try {
choice = userInput.nextInt();
}
catch (InputMismatchException e) {
userInput.next();
continue;
}
switch (choice) {
case 2: performSubtract();
break;
// ...
case 5: exit();
break;
}
}
userInput.close();
}
To the first question: try-catch block are usually used to see if your code are running through without error. By what you explain what you are trying to do, I would instead use a while-loop before the assignment for numberOne and numberTwo whether the input was float or not like:
// pseudo
while(input != float || input2 != float)
{
print(please reenter)
}
numberOne = input
numberTwo = input2

Only Accepting 2 as a number and giving wrong output of odd or even

Good morning,
I'm trying to learn somethings on my own. As I'm overloaded for assignments as it is. This is just a small practice program I was working on. I get it to this point however, I'm unsure of what is happening.
When given a number other than 2 it says "Please input a valid number, Thank you"
When given 2 it says "The Number is not even so there are Remainders"
I'm unsure why I'm getting this. Why is it not accepting other numbers and why is it saying 2 isn't even?
Any help on what I'm interpreting wrong would be appreciated. Thank you.
import java.util.Scanner;
public class Assignment1
{
//Scanner keyboard = new Scanner(System.in);
//int num = keyboard.nextInt();
public static int isEven()
{
Scanner keyboard = new Scanner(System.in);
int num = keyboard.nextInt();
switch (num)
{
case 1:
if (num % 2 == 0)
System.out.println("The Number is Even no Remainders");
break;
case 2:
if (num % 2 != 0);
System.out.println("The Number is not even so there are Remainders");
break;
default:
System.out.println("Please input a valid number, Thank you.");
}//switch
/*pull number from user
//store in num
//if even print message num is even
//else print message not an even number
* This is the remainder of my psuedcode notes to remind me how my
* mind was flowing
*/
return num;
} //isEven
public static void main (String args[])
{
Assignment1.isEven();
}//main
}//public class assignment one
The documentation for switch-case is here .
And now try this, I added some comment to lines. Read those carefully.
public class Assignment1 {
public static int isEven() {
Scanner keyboard = new Scanner(System.in);
int num = keyboard.nextInt();
num = num % 2; // divide by 2 and get a remainder.
switch (num) {
case 0: //case 0 means if number equal to zero
System.out.println("The Number is Even no Remainders");
break;
case 1: // case 1 means if number equal to one
System.out.println("The Number is not even so there are Remainders");
break;
default: // if no one match if not a valid.
System.out.println("Please input a valid number, Thank you.");
}//switch
/*pull number from user
//store in num
//if even print message num is even
//else print message not an even number
* This is the remainder of my psuedcode notes to remind me how my
* mind was flowing
*/
return num;
} //isEven
public static void main(String args[]) {
Assignment1.isEven();
}//
}

Execution of do while loop in the Java Calculator program

In my Java Program, I have used a Boolean variable 'decision' which should execute the actual calculator code in the 'do loop code block' only when the variable is true, but the do while loop is executed anyways even when the decision variable is false. I am using Eclipse IDE for Java and JDK 10 (both are recent versions). Please help me with a solution. The code is as below
import java.util.Scanner;
public class apples {
public static void main(String[] args) {
int option,a,b,c;
boolean decision;
System.out.println("We are here to create a calculator");
System.out.print("Do you want to switch on the calculator:");
Scanner yogi = new Scanner(System.in);
decision = yogi.nextBoolean();
do {
System.out.println("Following operations are available to perform:");
System.out.println("1. Addition");
System.out.println("2. Subtraction");
System.out.println("3. Multiplication");
System.out.println("4. Division");
System.out.print("Enter the operations do you want to perform:");
option = yogi.nextInt();
System.out.println("Choice of operation is:"+option);
switch(option) {
case 1:
System.out.println("Enter two numbers to be added:");
a = yogi.nextInt();
b = yogi.nextInt();
c = a + b;
System.out.print("Addition:"+c);
break;
case 2:
System.out.println("Enter two numbers to be subtracted:");
a = yogi.nextInt();
b = yogi.nextInt();
c = a - b;
System.out.print("subtracted:"+c);
break;
case 3:
System.out.println("Enter two numbers to be multiplied:");
a = yogi.nextInt();
b = yogi.nextInt();
c = a * b;
System.out.print("multiplied:"+c);
break;
case 4:
System.out.println("Enter two numbers to be divided:");
a = yogi.nextInt();
b = yogi.nextInt();
c = a / b;
System.out.print("divided:"+c);
break;
default:
System.out.println("This is a wrong choice");
break;
}
}while(decision==true);
}
}
the do while loop is executed anyways even when the decision variable
is false
A do...while will executes the body once before checking the condition.
Either modify your code for while or add an if-else enclosing do...while.
You can add another case 5 and in that write System.exit(0) for the successful termination of the program.
In the while part pass (option != 5). This should run the program.
You don't need decision variable.

Why does my Java calculator pause at loop?

After calculator() has ran, my program pauses...unless I enter an input to unpause the program. Then it continues to run and it prints out. However the input that I entered earlier to unpause the program is stored into answer. Please read my comments in the code to have a better understanding. If you still don't understand then feel free to copy the code to see what I am talking about.
public static void main(String[] args) {
boolean repeat = true;
while (repeat){
calculator(); //-Program pauses after this has ran.
System.out.println("Do you wish to repeat(y/n)?"); // This does not appear unless I enter an input.
String answer = userInput.next(); //The input that I entered earlier to unpause the program gets stored into answer.
if (answer.equalsIgnoreCase("y")){
repeat = true;
} else { repeat = false;}}} //Program terminates here because the input that I used to unpause the program isn't "y".
Full code below:
package calculatorAttempt;
import java.util.Scanner;
class CalculatorV2 {
static Scanner userInput = new Scanner(System.in);
public static void calculator(){
System.out.print(":");
if (userInput.hasNextInt()){
int num1 = userInput.nextInt();
System.out.print(":");
String inString = userInput.next();
System.out.print(":");
int num2 = userInput.nextInt();
System.out.print("=");
if (inString.equals("+")){
System.out.print(num1+num2);}
if (inString.equals("-")){
System.out.print(num1-num2);}
if (inString.equals("*")||(inString.equalsIgnoreCase("x"))){
System.out.print(num1+num2);}
if (inString.equals("/")){
float intTofloat = (float)num1/num2;
System.out.println(intTofloat);} }//If Integer
if (userInput.hasNextFloat()){
float num1 = userInput.nextFloat();
System.out.print(":");
String inString = userInput.next();
System.out.print(":");
float num2 = userInput.nextFloat();
System.out.print("=");
if (inString.equals("+")){
System.out.print(num1+num2);}
if (inString.equals("-")){
System.out.print(num1-num2);}
if (inString.equals("*")||(inString.equalsIgnoreCase("x"))){
System.out.print(num1*num2);}
if (inString.equals("/")){
System.out.print(num1/num2);} }//If Float
}//Public Void Calculator
public static void main(String[] args) {
boolean repeat = true;
while (repeat){
calculator();
System.out.println("Do you wish to repeat(y/n)?");
String answer = userInput.next();
if (answer.equalsIgnoreCase("y")){
repeat = true;
} else { repeat = false;}}
}//Main
}//Class
I am beginner so please bear with me :^) . Thanks.
This happens because of this line:
if (userInput.hasNextFloat()){
The hasNext...() methods in Scanner are blocking methods. They block if there is no input other than white space in the scanner, waiting for something to be entered. As soon as something real (not spaces or newlines) is entered, then they check whether it is a float, an int or whatever, and return a true/false reply to you.
After you finish an integer calculation, your program calls hasNextFloat(), and therefore, it blocks, waiting until you enter something. If that something is not a float, it will return false, and the if will not work.
You can experiment a little and see:
If you run your program and start with a float (say, 17.2), the program will show you the Do you wish to repeat? question after it calculates the result.
If you run your program and start with an int, and then, after you get the result, enter a float, it will print the : that is asking you for the float operator.
So basically, that should not be an if. It should be an else if structure.
Just use else if instead of if to check userInput.hasNextFloat().
Your code sample will look like.
if (userInput.hasNextInt()){
int num1 = userInput.nextInt();
....
....
....
} else if (userInput.hasNextFloat()){
float num1 = userInput.nextFloat();
....
....
...
}
You must use hasNext() instead of hasNextInt() and remove the if(hasNextFloat()) part. And use the Number class because it accepts both ints and floats:
if (userInput.hasNext()) {
Number num1 = userInput.nextByte();
System.out.print(":");
String inString = userInput.next();
System.out.print(":");
Number num2 = userInput.nextByte();
System.out.print("=");
switch (inString) {
case "+":
System.out.print(num1.doubleValue() + num2.doubleValue());
break;
case "-":
System.out.print(num1.doubleValue() - num2.doubleValue());
break;
case "*":
case "x":
case "X":
System.out.print(num1.doubleValue() * num2.doubleValue());
break;
case "/":
double intTofloat = num1.doubleValue() / num2.doubleValue();
System.out.println(intTofloat);
break;
default:
System.out.println(INVALID OPERATOR!);
break;
}
}

Categories