I am a little confused on what do after the catch statement in my code. After the exception is thrown and caught in the loop, the loop becomes infinite. I also found that entering a very long sequence (+10 or so) of numbers will cause the loop to go infinite. I am fairly new at exception handling in java, so a detailed description would be very educational.
public static void main(String[] args)
{
boolean cont = false;
while (!cont)
{
addInputNumber();
cont = tryAgain();
}
}
private static void addInputNumber ()
{
boolean valid;
int total;
int inputInt;
#SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
do
{
try
{
System.out.print("Enter a number(between 0 and 1000)");
inputInt = input.nextInt();
if(inputInt > 0 && inputInt < 1000)
{
valid = true;
total = (inputInt % 10) + ((inputInt / 10) % 10) + (inputInt / 100);
System.out.println("\n" + "The total of " + inputInt + " is " + total);
}
else
{
System.out.println("\n" + "ERROR---ENTER A NUMBER BETWEEN 0 AND 1000" + "\n");
valid = false;
}
}
catch(InputMismatchException ex)
{
System.out.println("\n" + "ERROR---ENTER A NUMBER BETWEEN 0 AND 1000" + "\n");
valid = false;
}
} while(!valid);
}
Change
catch(InputMismatchException ex)
{
System.out.println("\n" + "ERROR---ENTER A NUMBER BETWEEN 0 AND 1000" + "\n");
valid = true;
}
On the catch block, your variable valid was set to false.
Then on the code
while(!valid)
The condition will be true, and the loop go infinite
Your do while loop must end with
while(valid);
Because, once you catch the exception valid becomes false, and you may want to exit the loop if the exception is caught
What does the method tryAgain() do?
It looks like it calls addInputNumber(), right? If so, you don't need the loop in within the method addInputNumber().
I think you're problem is not of what to do in the catch block, but of program structure. You're using two loops, and you probably just need one. You could have addInputNumber() to return a boolean.
Related
Sorry for the newbish question, am quite new with Java.
So I want to display an error message when user input is outside of the bounds (Lesser than 0, greater than 100) which I've managed to do but I also want that the user can try again but my current code only continues with the execution of the program.
This is what I have now:
import java.util.Scanner;
public class storeQuota {
public static void main(String [] args) {
Scanner input = new Scanner (System.in);
int quotas [] = new int [100];
int NumberOfWorkers = 100;
for (int i = 0; i<numberOfWorkers; i++) {
if (i == 0) {
System.out.print("Enter the quota for the 1st student: ");
}
else if (i == 1) {
System.out.print("Enter the quota for the 2nd student: ");
}
else if (i == 2) {
System.out.print("Enter the quota for the 3rd student: ");
}
else if (i >= 3) {
System.out.print("Enter the quota for the " + (i+1) + "th student: ");
}
while (true) {
quotas[i] = input.nextInt();
if (quotas[i] > 100 || quotas[i] < 0)
System.out.println("Error - Can only be between 0 and 100.");
break;
}
}
//Printing all quotas.
System.out.println("Thank you for your input. Your entered quotas are: ");
for (int i=0; i<numberOfWorkers; i++)
{
System.out.print(quotas[i] + ", ");
}
input.close();
}
}
With this code, the error message is correctly displayed when a user inputs an int that isn't between 0 and 100 but the user will be unable to try again, the program continues to ask for the next quoata.
I think the problem is located in this line
break;
after
System.out.println("Error - Can only be between 0 and 100.");
which always breaks the while loop. Instead you only want to break the while loop if the input is in valid range. I would not use while(true) but some sort of conditional variable which is set to false in the while loop if the input is in valid range, also because while(true) is not a good programming practice from my point of view.
Your problem is using Break;
rather than using that, you should change the while(true) to while(false), you've also forgot to add curly brackets around the if statement.
boolean x = true;
while (x){
quotas[i] = input.nextInt();
if (quotas[i] > 100 || quotas[i] < 0){
System.out.println("Error - Can only be between 0 and 100.");
x = false;
}
}
also I suggest learning exceptions as they would make this 10x easier.
When executed, "break" breaks the loop you are currently in. In your code, break is executed irrespective of what the input is resulting in the unwanted result.
Simplest solution would be (closest to your original code):
while(true) {
quotas[i] = input.nextInt();
if (quotas[i] > 100 || quotas[i] < 0) {
System.out.println("Error - Can only be between 0 and 100.");
} else {
break;
}
}
Here, the loop will break only if correct input is entered.
You haven't used curly braces in if condition.
while (true) {
quotas[i] = input.nextInt();
if (quotas[i] > 100 || quotas[i] < 0) {
System.out.println("Error - Can only be between 0 and 100.");
break;
}
}
I'm making a simple program that is a guessing game all you need to do is guess the random number. As long as your not getting the correct answer it will keep asking for input.
I created two exceptions which is thrown if the input value is high or low which works.
I also needed to use another exception which is InputMismatchException but when its used its giving me an infinite loop. Instead of asking the user for input it just skips directly to the InputMismatchException. How do I get it to work with my custom exceptions?
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
final int min = 1, max = 50;
final int random = (int) Math.floor(Math.random() * (max - min + 1) + min);
boolean status = false;
int count = 0;
while (status != true) {
try {
System.out.println("Guess a number from 1 to 50: ");
int answer = scan.nextInt();
if (answer < random) {
throw new InputTooLowException("");
} else if (answer > random) {
throw new InputTooHighException("");
} else if (answer == random) {
System.out.println("\n" + "Congratulations! You got it in " + count + " attempt/s");
status = true;
}
} catch (InputTooLowException e) {
System.out.println("Too low. Try again.");
status = false;
count = count + 1;
} catch (InputTooHighException e) {
System.out.println("Too high. Try again.");
status = false;
count = count + 1;
} catch (InputMismatchException e) {
System.out.println("Invalid Input");
status = false;
}
}
}
}
This program works for me.
Again, I want to highlight that this is a bad/non-idiomatic use of Exceptions.
I highly recommend Joshua Blochs famous Book "Effective Java". Chapter 10, Item 69 is about this: "Use exceptions only for exceptional conditions".
The Carnegie Mellon University Software Engineering Institute also has this in their coding guidelines.
Now regarding the infinite loop: I didn't realize that InvalidInputException is not one of your custom Exceptions, but from java.util and thrown by scan.nextInt.
The documentation of Scanner says:
When a scanner throws an InputMismatchException, the scanner will not pass the token that caused the exception, so that it may be retrieved or skipped via some other method.
That means, if you type in text, not a number, Scanner will let you know, but not simply throw away the input. You have to handle it yourself. E.g., by calling next. I have added a check hasNext here. A user could press Ctrl+d which means something like "End of File" (EOF). This closes the input stream. My check prevents an error here, but your call to nextInt may then throw a NoSuchElementException. This should be handled in real code, but I doubt your professor will notice.
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
final int min = 1, max = 50;
final int random = (int) Math.floor(Math.random() * (max - min + 1) + min);
boolean status = false;
int count = 0;
while (status != true) {
try {
System.out.println("Guess a number from 1 to 50: ");
int answer = scan.nextInt();
// Note that this is a _terrible_ use of Exceptions
// and _bad practice_.
if (answer < random) {
throw new InputTooLowException("");
} else if (answer > random) {
throw new InputTooHighException("");
} else if (answer == random) {
System.out.println("\n" + "Congratulations! You got it in " + count + " attempt/s");
status = true;
}
} catch (InputTooLowException e) {
System.out.println("Too low. Try again.");
count = count + 1;
} catch (InputTooHighException e) {
System.out.println("Too high. Try again.");
count = count + 1;
} catch (InputMismatchException e) {
System.out.println("Invalid Input");
// Check if there actually is an invalid token
if (scan.hasNext()) {
// Discard invalid token
scan.next();
}
}
}
}
// Defining Exceptions here, but could do it in their own files.
private static class InputTooHighException extends Exception {
public InputTooHighException(String msg) { super(msg); }
}
private static class InputTooLowException extends Exception {
public InputTooLowException(String msg) { super(msg); }
}
}
There's two things I'm needing help with. Loop issue 1) I have to initialize this variable outside of the loop, which makes the loop fail if the user inputs a string. Is there a way around that? Basically, if I set N to anything then the do-while loop just immediately reads it after getting out of the
import java.util.Scanner;
/**
* Calculates sum between given number
*/
public class PrintSum {
public static void main(String[] args) {
int N = 0;
String word;
boolean okay;
Scanner scan = new Scanner(System.in);
System.out.print("Please enter a number from 1-100: ");
do {
if (scan.hasNextInt()) {
N = scan.nextInt();
} else {
okay = false;
word = scan.next();
System.err.print(word + " is an invalid input. Try again. ");
}
if (N > 100 || N < 1) {
okay = false;
System.err.print("Invalid Input. Try again. ");
} else {
okay = true;
}
} while (!okay);
loop(N, 0);
}
public static void loop(int P, int total) {
while (P >= 1) {
total = total + P;
P--;
}
System.out.println(total);
}
}
If not, then the issue becomes, how do I solve this? I thing that I need to be able to say
if (scan.hasNextInt() || ??? > 100 || ??? < 1) {
okay = false;
word = scan.next();
System.err.print(word + " is an invalid input. Try again. ");
} else {
okay = true;
}
What do I put in the ??? to make this work? I think I just don't know enough syntax.
Thank you!
Why don't you try this?
do {
if (scan.hasNextInt()) {
N = scan.nextInt();
} else {
okay = false;
word = scan.next();
System.err.print(word + " is an invalid input. Try again. ");
continue;
}
if (N > 100 || N < 1) {
okay = false;
System.err.print("Invalid Input. Try again. ");
continue;
} else {
okay = true;
}
} while (!okay);
break is used to end the loop as soon as the user enters the invalid character(condition of the else clause), so the loop doesn't fail.
Looking at your edited question, continue is what you are looking for if you might want to allow the user to enter another value after entering the invalid value.
Use break or continue based on requirement. More on breaks and continue.
Your second approach can be solved as follows:
if (scan.hasNextInt()){
N = scan.nextInt();
if (N > 100 || N < 1) {
System.err.print("Invalid input. Try again. ");
}
//perform some operation with the input
}
else{
System.err.print("Invalid Input. Try again. ");
}
I'm trying to make a little, basic game of Nim. I'm a beginner in java. When I run the code, it just runs for a second, and stops without doing what I ask of it. It's probably a simple solution but I had to ask. Does anyone have any idea? Here's my code.
import java.util.Scanner;
import java.util.Random;
public class Nim {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Random rand = new Random();
int playernum;
int cpunum = rand.nextInt(3)+1;
int gamenum = 21;
boolean win = false;
boolean turn = true;
while((win = false) && (turn = true)){
System.out.println("The number is 21. Enter a number from 1 - 3");
playernum = input.nextInt();
int remaining = gamenum - playernum;
System.out.println("The number is now " + remaining);
turn = false;
if((turn = false) && (gamenum > 0)){
System.out.println("Computer is thinking...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
When using boolean variables in if statements and loop headers, there's no need to check if they equal true or false, just use the variables themselves like so,
while(!win && turn){
System.out.println("The number is 21. Enter a number from 1 - 3");
playernum = input.nextInt();
int remaining = gamenum - playernum;
System.out.println("The number is now " + remaining);
turn = false;
if(!turn && gamenum > 0){
System.out.println("Computer is thinking...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Also, another issue before was that when you were checking the boolean variables you were using the wrong operator =. You should have used == to compare equality between primitive types but with booleans it's not necessary. If you wanna check if a boolean variable is true, just use the boolean variable itself as the condition. And if you wanna check if a boolean variable is 'false', just use the negation of the boolean variable by using the ! operator in the condition.
Can someone explain how I can end the program after hitting the 'capacity exceeded' message without using a break or system.exit, but continue to prompt for 'leaving' and 'entering' if the message is not reached?
Also, for the 'capacity exceeded' message it also displays the totalPeople. totalPeople in this section becomes however many people I enter to leave or enter. How can I make so it's the totalPeople stored before I enter the leave or enter values to make it exceed capacity?
int numLeaving = Integer.parseInt(JOptionPane.showInputDialog("number leaving"));
int numEntering = Integer.parseInt(JOptionPane.showInputDialog("number entering:"));
while (totalPeople <= 65 && totalPeople >= 0) {
try {
if (numLeaving >= 0 && numEntering >= 0) {
totalPeople = (totalPeople + numEntering) - numLeaving;
JOptionPane.showMessageDialog(null,"Total people = " + totalPeople);
}
else {
JOptionPane.showMessageDialog(null,"Invalid data");
}
}
catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null,"Enter numbers only");
}
if (totalPeople > 65) {
JOptionPane.showMessageDialog(null,"Capacity exceeded\n" + "Total people = " + totalPeople);
}
numLeaving = Integer.parseInt(JOptionPane.showInputDialog("number leaving"));
numEntering = Integer.parseInt(JOptionPane.showInputDialog("number entering:"));
}
I think you should save your limit of people that could enter in a constant. Like this:
static final int maximumPeople = 65;
So now you can use it for conditions in your loops and whatever you want:
while (totalPeople <= maximumPeople && totalPeople >= 0)
{
//code
}
if (totalPeople > maximumPeople) {
//code
}
And another variable that you are going to modify, in your case, totalPeople. In this case, you can show your message of the total of people that can enter:
if (totalPeople > maximumPeople)
{
JOptionPane.showMessageDialog(null,"Capacity exceeded\n" + "Total people = " + maximumPeople);
}
But it also will leaves your loop because you are using totalPeople (the real number of people that has entered).
I expect it will be helpful for you!
To do not continue looping, we have to make the looping condition false:
if (totalPeople > 65) {
JOptionPane.showMessageDialog(null,"Capacity exceeded\n" + "Total people = " + totalPeople);
totalPeople = -1;
}
The rest of loop code will be executed, but it will not entering while loop again.
If you want to keep the value of totalPeople, the easiest way is to add a boolean variable and use it in the condition of looping:
boolean exit= false;
while (totalPeople <= 65 && totalPeople >= 0 && !exit) {
// ..
if (totalPeople > 65) {
JOptionPane.showMessageDialog(null,"Capacity exceeded\n" + "Total people = " + totalPeople);
exit= true;
}
// ..
Put the current code in a while loop and store the totalPeople in another variable.