do while loop with a Yes/No user prompt - java

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

Related

How to type correct answer in the last try without showing the game over text

I am a beginner and as you can see I made a simple Java game.
The user has 5 tries to guess a number between 1 and 20.
If the user wins a congratulations message will show.
If the user didn't succeed a game over message will pop up.
Issue
When the user enters the right answer on the 5th try both congratulations and game over messages will pop up.
Code
package org.meicode.Loops;
import java.util.Objects;
import java.util.Random;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
System.out.println("Welcome");
System.out.println("Enter your name please ");
Scanner scanner = new Scanner(System.in);
String name = scanner.next();
System.out.println("Hello " + name);
System.out.println("Type 1 to start the game");
int yes = scanner.nextInt();
while (yes != 1) {
System.out.println("Type 1 to start the game");
yes = scanner.nextInt();
}
System.out.println("Guess the number in my mind,It is between 1 and 20 and you got 5 tries");
int timestried = 0;
Random random = new Random();
int x = random.nextInt(20) + 1;
while (timestried < 5) {
timestried++;
Scanner scanner1 = new Scanner(System.in);
int answer = scanner.nextInt();
if (x == answer) {
System.out.println("Well done, you did it");
} else if (x > answer) {
System.out.println("Try again,hint:the value is bigger than what you typed");
} else if (x < answer) {
System.out.println("Try again,hint:the value is smaller than what you typed");
}
}
System.out.println("Game over, the number was " + x);
}
}
How can I fix it?
Here is my attempt. I have added some comments in the code to help you.
Note that I have changed some of the file names to, so you may need to change them back for it to run, or just copy the main code section:
package com.misc;
import java.util.Objects;
import java.util.Random;
import java.util.Scanner;
public class GameTest {
public static void main(String[] args) {
System.out.println("Welcome");
System.out.println("Enter your name please ");
Scanner scanner = new Scanner(System.in);
String name = scanner.next();
System.out.println("Hello " + name);
System.out.println("Type 1 to start the game");
int yes = scanner.nextInt();
//We initialize the answer variable here to use it later on.
int answer = 0;
while (yes != 1) {
System.out.println("Type 1 to start the game");
yes = scanner.nextInt();
}
System.out.println("Guess the number in my mind,It is between 1 and 20 and you got 5 tries");
int timestried = 0;
Random random = new Random();
int x = random.nextInt(20) + 1;
//Print out the randomly generated number so we can test it. We answer wrong 4 times then put in the right answer to see if the message is fixed.
System.out.println("Testing: the answer is " + x);
while (timestried < 5) {
timestried++;
Scanner scanner1 = new Scanner(System.in);
answer = scanner.nextInt();
if (x == answer) {
System.out.println("Well done, you did it");
} else if (x > answer) {
System.out.println("Try again,hint:the value is bigger than what you typed");
} else if (x < answer) {
System.out.println("Try again,hint:the value is smaller than what you typed");
}
}
//This is the conditional that uses the answer variable we declared earlier above to avoid printing out the Game Over message in a success scenario.
if (x != answer) {
System.out.println("Game over, the number was " + x);
}
}
}
Here is proof that it works. I made the program print out the real answer, answered wrong 4 times and correctly the 5th time.
Simple fix
There are 2 things I would add to your code to achieve the desired behavior:
break or exit the loop on correct answer
set a flag signaling the question was solved to later build the message upon it
Basics: How to break loops and why
You can achieve this by two ways:
break the loop when the user typed the correct answer
add an exit-condition to the loop
return from the whole method prematurely
throw an exception that can either be caught outside or will also exit the method
I will explain (1) and (2) here in this answer (3) in a separate answer.
(1) Breaking the loop
The loop shall continue until:
the maximum number of tries has been reached
the correct answer was given
Use a break; statement to break the loop if correct answer:
if (x == answer) {
System.out.println("Well done, you did it");
break;
}
Note: contrary a continue; will skip further loop-body and jump to the next iteration.
(2) add a flag signaling premature exit (e.g. correct answer)
You can add a flag that is set to true if the user types the correct answer:
boolean userHasAnsweredCorrect = false;
while (timesTried < 5) { // here the flag can be added instead breaking
if (x == answer) {
System.out.println("Well done, you did it");
userHasAnsweredCorrect = true;
break;
}
}
// omitted some lines .. then at the end
if (userHasAnsweredCorrect) {
System.out.println("You beat the game!")
} else {
System.out.println("Game over, the number was " + x);
}
See how you define the flag before the loop, set it inside the loop (together with a break;) and then test on the flag after the loop.
Combined: set flag and add exit-condition
boolean userHasAnsweredCorrect = false;
while (timesTried < 5 && !userHasAnsweredCorrect) { // here the break happens instead
if (x == answer) {
System.out.println("Well done, you did it");
userHasAnsweredCorrect = true;
// break;
}
}
Find 2 more simpler ways of breaking the loop in my other answer, here follows the 3rd way:
Put the whole game into a method like startGame() and exit from that. Either exit after loop with max-tries has finished or inside the loop (prematurely) if answered guess was correct.
(3) Exiting the loop and method using return
That premature method-exit can be achieved by inserting a return; inside the loop.
public void startGame() {
// rest of preparation
// starting the game-loop
for (int i = 1; i <= maxTries; i++) { // for-i is indexed and safer (no infinite-loop)
// read input
// score or evaluate answer against x
if (x == answer) {
System.out.println("Well done, you did it");
return; // exit the method, not reaching "game-over" after the loop
}
// continue the iteration
}
// game-over (if not previously exited because of victory)
}
To have an exit-condition for the for loop, define int maxTries = 5 either as local variable, class field or constant.

While loop is endless because the break point doesn't work

I'm trying out the code below but I'm getting a endless loop. The break point doesn't seem to help at all.
import java.util.Scanner;
public class Question2 {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter ID Number: ");
int studentSn = keyboard.nextInt();
System.out.print("Enter your Marks: ");
int Score = keyboard.nextInt();
Scanner scan = new Scanner(System.in);
boolean stop = false;
String answer = "";
String Grade = "";
String msg = "";
int counter = 0;
while (!stop) {
if (Score < 50) {
Grade = "F";
} else if (Score <= 64) {
Grade = "P";
} else if (Score <= 74) {
Grade = "C";
} else if (Score <= 84) {
Grade = "D";
} else if (Score <= 100) {
Grade = "HD";
} else {
msg = "Invalid Input";
}
if (Grade != null) {
System.out.println("Student Serial Number: " + studentSn);
System.out.println("Your Grade is: " + Grade);
System.out.println("Do you want to continue (yes/no): " + answer);
} else {
System.out.println("Student Serial Number: " + studentSn);
System.out.println(msg);
System.out.println("Do you want to continue (yes/no): " + answer);
}
while (answer.equalsIgnoreCase("YES"));
{
counter++;
if (answer.equalsIgnoreCase("NO")) {
break;
}
}
}
}
}
There are multiple infinite loops in this scenario. With
while (!stop) {
// ...
}
you never set "stop" to true, meaning that the loop would end. The break statement in
while (answer.equalsIgnoreCase("YES"));
{
counter++;
if (answer.equalsIgnoreCase("NO")) {
break;
}
}
would only break out of that loop, not the !stop loop. If you wanted to break out of both loops, you'd need to do
MY_LABEL: while (!stop) {
// ...
while (answer.equalsIgnoreCase("YES"));
{
counter++;
if (answer.equalsIgnoreCase("NO")) {
break MY_LABEL;
}
}
or otherwise write stop = true; at some point. However, that is not the only endless loop in your code. In
while (answer.equalsIgnoreCase("YES"));
{
// loop body ^ problem here
}
your loop statement is followed by a semicolon! This should be
while (answer.equalsIgnoreCase("YES"))
{
// loop body
}
since your code right now is the same as writing
while (answer.equalsIgnoreCase("YES"))
; // do nothing
// loop body
because of how Java's syntax works. Your current code compiles because you can have a block without any loops or if statements
// do some stuff
{ // begin new scope
int x = 10;
} // end scope
int y = x; // error because x is not in scope!
but this is clearly not what you intended.
Beyond that, you never read anything into answer meaning it always equals ""-- it never equals "YES" or "NO" at all! At least somewhere you should be saying
answer = scan.nextLine();
to read input.
The entire program is a bit wonky though. Here's how I would lay it out:
// Instead of using "stop", we can just break out of the loop when we're done
while(true) {
// ...
// Prompt for input. I use "print" instead of "println" so that the user's answer will be on the same line as the question, e.g.
// Do you want to continue (yes/no): YES
// instead of
// Do you want to continue (yes/no):
// YES
// and so forth
System.out.print("Do you want to continue (yes/no): ");
// This is how we actually read input.
String answer = scan.nextLine();
// If the user doesn't say "YES" (this could be "NO" or "q" or "asdf" or anything else), break out of the loop
if(!answer.equalsIgnoreCase("YES"))
break;
}
I think you're a bit confused about how loops and input work. Just because you write System.out.println("my question: " + answer) doesn't mean that Java will read the rest of the line into answer. It'll actually write whatever is already in answer, for example
answer = "abc"
System.out.println("Question? " + answer);
// "Question? abc" will be printed, and no input will be read
// answer still equals "abc"
and additionally, if you want to ask a question repeatedly, you have to put all of that questioning into the loop. Java will not read anything new into answer until you readLine() again, so I think that's where the confusion about the while loop comes from. In your answer.equalsIgnoreCase("YES") loop, nothing new will be read unless you put answer = scan.readLine() in it.
You have two while loops going on, your attempt to break has not been executed correctly, is only exiting the inner loop.
Let strip your loop logic back to only describing the variables and logic that will affect the loop itself: I have replaced your other code with method calls to simplify the demo, assume that you already implemented these methods and that they do what the names infer.
This is a good technique for transitioning form pseudo code to actual code but just as useful for evaluating loop constructs that aren't going the way you planned
int studentSn = ReadInt("Enter ID Number: ");
int Score = ReadInt("Enter your Marks: ");
string answer = "";
boolean stop = false;
while(!stop) { // this is never ending, nothing ever sets stop to true
Grade = DetermineGrade(score);
if (Grade != null) {
ShowGrade(studentSn, Grade);
answer = ReadContinuePrompt();
} else {
ShowError(studentSn, "Invalid Input");
answer = ReadContinuePrompt();
}
while (answer.equalsIgnoreCase("YES"));
{
counter++;
if (answer.equalsIgnoreCase("NO")) {
break;
}
// If this user's input was not NO, then this loop is infinite and should run into a stack overflow error when the value of counter exceeds the max value of int
}
}
Your outer loop is based on a stop variable:
while (!stop)
So inside your loop logic, instead of using a break statement, all you need to do is set the value of stop to true. A carefully placed break statement could also do this, but coding a deliberate stop parameter the way you have is a good design that makes the intent very clear.
Now your inner loop is just wrong, I don't want to over analyse it, because you ask for the user input outside of the loop, there is no way to change the answer. So lets replace the inner loop with a simple conditional statement
if(answer.equalsIgnoreCase("NO"))
stop = true; // or break;
else
counter++;
Now we need to go back to how you have coded your outer loop. Again, because the main input is outside of the loop, there is no amount of times with this code where we can say "YES" that will give a different answer, we need to ask the score input inside the loop so the result can be changed
That now gives us this logic:
int studentSn = ReadInt("Enter ID Number: ");
string answer = "";
boolean stop = false;
while(!stop) {
// read the score inside the loop.
int Score = ReadInt("Enter your Marks: ");
Grade = DetermineGrade(score);
if (Grade != null) {
ShowGrade(studentSn, Grade);
answer = ReadContinuePrompt();
} else {
ShowError(studentSn, "Invalid Input");
answer = ReadContinuePrompt();
}
if(answer.equalsIgnoreCase("NO"))
stop = true; // or break;
else
counter++;
}

Unable to break out of For Loop in Java

I am a beginner and was making a small program to practice what i have learnt.
I was writing code to check the grade of a student.
This is the code :
import java.util.*;
public class Grader {
public static void main(String[] args) {
String studentName;
int rollNo = 0;
Scanner inputter = new Scanner(System.in);
System.out.println("Please enter the roll number of the student: ");
rollNo = inputter.nextInt();
System.out.println("Thank you. Now, please enter the student's name: " );
studentName = inputter.next();
for(int i=0; ; i++){
System.out.println("Please enter a valid examination type, i.e FA or SA: ");
String examType = inputter.next();
examType = examType.toUpperCase();
if(examType == "FA" || examType == "SA"){
break;
}
}
}
}
The problem I am facing is that even though I enter a valid examType, the For loop doesn't break.
You need to use String.equals().
Scanner.next() returns a String. Using == on a string doesn't give any errors but will test reference equality instead of value equality. It won't return true even if the strings are equal in value.
Correct code:
if(examType.equals("FA") || examType.equals("SA")){
break;
}
EDIT
OP mentioned in a comment that the loop is to run without ending until hitting break. You can create an infinite loop in either of these two ways:
for(;;){
//runs infinitely
}
OR
while(true){
//runs infinitely
}
Both of these infinite loops are broken with break. Also, you use less memory (albeit a small and almost insignificant difference) because you don't have a counter variable. In the next-to-impossible case that the user enters invalid input so many times that the integer overflows, not having a variable eliminates this risk. You also save processor time because there isn't an instruction to allocate memory or add one to the number.
public static void main(String args[]) {
String studentName;
int rollNo = 0;
Scanner inputter = new Scanner(System.in);
System.out.println("Please enter the roll number of the student: ");
rollNo = inputter.nextInt();
System.out.println("Thank you. Now, please enter the student's name: " );
studentName = inputter.next();
for(int i=0; ; i++){
System.out.println("Please enter a valid examination type, i.e FA or SA: ");
String examType = inputter.next();
examType = examType.toUpperCase();
if(examType.equals("FA") || examType.equals("SA")){
break;
}
}
}
This is working fine.
You haven't set a limit, for example
for(int i = 0; i < somevalue; i++)
otherwise a while loop might be a better choice like:
while(examType.equals("FA") || examType.equals("SA")
For best coding practice the usage of equals operation for Strings like below code snippet as per Sonar compliance standard.
("SA".equals (examType))

How do I make my program repeat according to certain circumstances?

import java.util.Scanner;
public class MyFirstGame {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Please Enter A Number: ");
double s = scanner.nextDouble();
double randomNumber = Math.random();
double realNumber = randomNumber*10;
double realerNumber = Math.round(realNumber);
System.out.println(realerNumber);
if(s==realerNumber) {
System.out.println("You Win!");
} else {
System.out.println("Try Again...");
}
}
}
So what I am trying to do is make a "game" for my Java class. I have generate a random number between 1 and 10 and the user has to input a number and if the input and the random number are the same, they "win." If they lose, they try again...? First, I did all the necessary scanner stuff that I don't even fully understand. I just copied the professor. So the program says to enter a number and the program generates a number between 0.0 and 1.0. I multiply that number by 10 to make it between 1 and 10. Then I round the number to the nearest integer. If the input matches this number, the program says you win. If not, it'll say try again.
The problem is how do I make the program repeat itself without the user having to reboot the program with the cmd? I need to repeat the input, random number generator, and then the result. What do I need to do? Also, how is my program? My second big one...yeah right...big. But seriously, how can I make it less complex or anything to improve it. Thanks.
Use a while loop:
long realerNumber = Math.round(realNumber);
// first guess
long guess = scanner.nextLong();
while (guess != realerNumber) {
System.out.println("Try Again...");
// guess again
guess = scanner.nextInt();
}
System.out.println("You Win!");
There is already a class to generate random numbers, you could use it:
// TODO: move to constant
int MAX = 10;
// nextInt(int n) generates a number in the range [0, n)
int randomNumber = new Random().nextInt(MAX + 1)
just put your code inside the do-while loop
Scanner scanner = new Scanner(System.in);
do
{
System.out.println("Please Enter A Number: ");
double s = scanner.nextDouble();
double realerNumber = Math.round( Math.random() * 10 );
System.out.println(realerNumber);
if(s==realerNumber) {
System.out.println("You Win!");
} else {
System.out.println("Try Again...");
}
}
while(someCondition);
the someCondition can be for example a counter (if you want to play n times just set counter to n and decrease it every loop iteration then check if it is 0 in while) or some function checking if a key is pressed (like escape)
int n = 5;
do
{
n--;
...
}
while(n > 0);
This will run forever, but it's the idea mentioned in the first comment
...
Scanner scanner = new Scanner(System.in);
while(true){ // add this after Scanner ... declaration
...
} // end of existing else block
} // end of while loop, so add this single brace
...

Trouble trying to restart my Java program

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.

Categories