Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Why does the output keep on running? When I run this program, and I enter the in the output, it keeps running, and doesn't let me enter any more numbers. Why is this happening?
import java.util.InputMismatchException;
import java.util.Scanner;
public class ExceptionTest2
{
public static void main(String[] args)
{
Scanner st = new Scanner(System.in);
int ab, bd, cde;
ab = bd = cde = 0;
boolean infinite, in;
do
{
System.out.println("Enter the numbers to divide");
infinite = false;
in = true;
try
{
ab = st.nextInt();
bd = st.nextInt();
infinite = false;
in = true;
}
catch (InputMismatchException e)
{
System.out.println("Invalid input");
in = true;
}
finally
{
if (in)
{
try
{
System.out.println("I am in try block before exception");
cde = ab / bd;
System.out.println("I am in try block after exception");
}
catch (Exception e)
{
infinite = true;
}
finally
{
if (!infinite)
{
System.out.println("Answer is " + cde);
};
}
}
}
}
while (cde != 100);
st.close();
}
}
problem:
ab = st.nextInt();
When you input a String on it I wont get consumed by the nextInt and no one will thus giving you infinite loop
solution:
You need to consume those characters that you inputted in your catch block to avoid the infinite loop
sample:
catch (InputMismatchException e) {
System.out.println("Invalid input");
st.nextLine();
in=true;
}
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
public class TryCatch {
public static void main(String[] args) {
int Score[] = {5,3,9}; //my array
Scanner sc = new Scanner(System.in);
boolean flag=true; //boolean for the while loop that will keep on asking for input till the input is correct
System.out.println("Enter index: ");
int ind = sc.nextInt(); //taking input
while(flag){
try {
System.out.println("Value at index is = " + Score[ind]);
flag= false; //if input is correct, the bool turns false and loop stops
} catch (Exception e) {
System.out.println("Enter a valid value!");
ind = sc.nextInt(); //should ask for input again if the input isn't right
}
}
}
}
So the problem I am having is that the catch block works for ArrayOutOfBound exception, but not when I enter some other character like a letter. What should I do?
UPDATE:
I fixed the bug by creating a new instance of the scanner class object in the catch block.
sc = new Scanner(System.in);
Thank you all for your answers.
You need to initialize the scanner class object again to close the previous scanner and dump all the input in it.
Add this line to the end of your catch block-
sc = new Scanner(System.in);
It is happening because you are asking for integer input within the catch, which isn't handled anywhere else, try this:
int ind; //taking input
while(flag){
try {
find = sc.nextInt();
System.out.println("Value at index is = " + Score[ind]);
flag= false; //if input is correct, the bool turns false and loop stops
} catch (Exception e) {
System.out.println("Enter a valid value!");
continue;
}
}
The problem is that the exception is thrown outside of the try block. You read from the keyboard either before the try-catch block or in the catch block.
If an exception is thrown within a catch block that exception will not be caught. Also you need to clear the input with nextLine or you will get an infinite loop, the correct code would be as follows:
System.out.println("Enter index: ");
while (flag) {
try {
int ind = sc.nextInt(); //taking input
System.out.println("Value at index is = " + Score[ind]);
flag = false; //if input is correct, the bool turns false and loop stops
} catch (Exception e) {
System.out.println("Enter a valid value!");
sc.nextLine();
continue;
}
}
I believe you need to separate the exceptions (when catching multiple types) with a pipe operator (SQLException | IOException e)
for example.
I'm trying to make a timer for a simple math quiz where user needs to answer the question within 10 seconds, and when that time exceeds, it will load to the next question.
I found the solution to implement Executorservice and future, but I'm having a problem when it keeps repeating the loop for invalid input (numberformat exception) when user enter other input than integers at my Game class.
Hope this is useful to know:
class MathQuestion (where the math questions are generated), Game (the game round initiated), and GameTimer.
Game class:-
//for 10 rounds of game
for (int i=0; i<rounds; ++i)
{
System.out.println("*************************************");
System.out.println("\nRound " + (i+1)
+ "\nEnter 'x' to quit game");
System.out.println("\nQuestion:");
//call method to generate question and get correct answer
result = quiz.Questions();
System.out.println("You have 10 seconds");
//to make sure we read a line or interrupt it for the timer
ExecutorService ex = Executors.newSingleThreadExecutor();
try
{
//retrieve the actual result at a later point in time.
Future<String> ans = ex.submit(new GameTimer());
try {
boolean validInput = false;
do
{
System.out.println("\nEnter your answer: ");//prompt user input answer
//10 secs wait to obtain result from player
//wait until callable complete before return result
answer = ans.get(10, TimeUnit.SECONDS);
//answer = scan.nextLine();
try
{
//valid player input
pAnswer = Double.parseDouble(answer.trim()) ; //convert to double
validInput = true;
}catch (NumberFormatException e){ //other input other than integers *this the repeated loop
System.out.println("Invalid input. Please try again.");
validInput = false;
ans = ex.submit(new GameTimer()); //resubmit task solution
}
if (answer.trim().equalsIgnoreCase("x")) //player quit game
{
quit=true;
break;
}
}while (!validInput);
if (quit)
{
break;
}
//for correct answer
if (Math.abs(Double.parseDouble(answer) - quiz.answer) <= 0.01) {
//add 10 points
this.gamer.setScore(score+=10);
System.out.println("You got it right!");
}
else //wrong answwer
{
//subtract 10 points
this.gamer.setScore(score-=10);;
System.out.println("You got it wrong!");
}
} catch (InterruptedException ex1) {
Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex1);
} catch (ExecutionException ex1) {
Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex1);
} catch (TimeoutException ex1) {
System.out.println ("\nTime's up! Better luck next time~");
}
}finally {
ex.shutdownNow(); //stop all running tasks and shut the executor down immediately.
}
}
GameTimer class:-
public class GameTimer implements Callable<String> {
public String call() throws IOException {
BufferedReader inp = new BufferedReader(new InputStreamReader(System.in));
String input = "";
while ("".equals(input)) {
try {
while (!inp.ready()) {
Thread.sleep(1000);
}
input = inp.readLine();
} catch (InterruptedException e) {
return null;
}
}
return input;
}
}
Here is a picture of the output loop problem: loop problem
I have been trying to find solutions for timer a really long while now, I would really appreciate it if anyone could help.
Thank you so much.
*additional : Is there a way to display that timer countdown (eg: 10 9 8..) but with erasing the previous second when the new second count comes up?
(without erasing suggestion would also help, thank you! )
You cannot keep re-calling get. Your task is an executable, you submit it and it gets run. You call .get and it gets the result of your execution. You need to re-submit the task, for example:
catch (NumberFormatException e){ //other input other than integers *this the repeated loop
System.out.println("Invalid input. Please try again.");
validInput = false;
ans = ex.submit(new GameTimer());
}
You might want to keep track of the time elapsed since each time you call get you're using the same timeout.
In my opinion, you should put the error handling in your callable.
final String question = "Enter double value";
Callable<Double> getDouble = ()-{
BufferedReader inp = new BufferedReader(neww InputStreamReader(System.in));
while (!Thread.currentThread().isInterupted()) {
System.out.println(question);
try {
String input = inp.readLine();
Double v = Double.parseDouble(v);
return v;
} catch(Exception e){
if( Thread.currentThread().isInterrupted()){
return null;
}
System.out.println("Invalid Input, try again");
}
}
}
Now when you submit the task, you don't have to worry about an invalid double because it is handled in the callable task.
Future<Double> ans = ex.submit(getDouble);
Double v = ans.get(10, TimeUnit.SECONDS);
This will leave one problem: the task, even if canceled will still be waiting on the standard input. The easiest way to fix this is to tell your user to press enter to continue.
This question already has answers here:
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
(5 answers)
Closed 6 years ago.
boolean z = false;
do {
try {
a = sc.nextInt();
z = true;
}
catch(Exception e) {
}
}
while(!z);
Try this. If you try an integer the first time it executes properly. However if you enter the wrong type of text it turns into an infinite loop even if you enter an int next and skips assigning the boolean value to true. Why is this?
Your problem is from not handling the end of line token and so the scanner is left hanging. You want to do something like so:
import java.util.Scanner;
public class Foo2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = 0;
boolean catcher = false;
do {
try {
System.out.print("Enter a number: ");
a = sc.nextInt();
catcher = true;
} catch (Exception e) {
} finally {
sc.nextLine();
}
}
// !!while(catcher == false);
while (!catcher);
System.out.println("a is: " + a);
}
}
Also, while (z == false) is bad form. You're much better off with while (!z). This prevents the while (z = false) error, and is a cleaner way of expressing this.
edit for Marcelo:
Marcelo, thanks for your input and advice! Are you saying that the conditional in the if block below will not change the value of the boolean, spam?
boolean spam = true;
if (spam = false) {
System.out.println("spam = false");
}
System.out.printf("spam = %b%n", spam);
Because if it does change it, the coder wouldn't expect this if they intended to write if (spam == false), then there could be subtle and dangerous side effects from this. Again, thanks for helping to clarify this for me!
I would like the program to re-do the while loop when it catches the exception - the exception being receiving a number zero. Instead it continues a while loop with the code below, I would like it to ask for the user input again until the user inputs a number that is different by zero.
import java.util.InputMismatchException;
import java.util.Scanner;
public class whilePerjashtim {
public static int division(int a, int b){
return a/b;
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int a, b;
System.out.println("Enter a value: ");
a = s.nextInt();
while(true){
try
{
System.out.println("Enter b value");
b = s.nextInt();
System.out.println("Sum of division is: " + division(a,b));
}
catch(ArithmeticException e)
{
System.err.println("Don't divide by zero!!!");
}
catch (java.util.InputMismatchException e)
{
System.err.println("Enter just a Number!!!");
}
finally
{
System.out.println();
}
}
}
}
Use something of the following form (not exact Java for your homework problem)
boolean validInput = false;
while (!validInput) {
.. get input
.. set validInput = true if no error
.. catch error
.. print try again message
}
You can set a boolean value, that determines, if the while loop ends succesfully. Then in every loop you start by assuming the value is true and when an exception is raised, you set it to false.
boolean success = false;
while(success == false){
success = true;
try {
System.out.println("Enter b value");
b = s.nextInt();
System.out.println("Sum of divison is: " + division(a,b));
}
catch(ArithmeticException e) {
System.err.println("Dont divide by zero!!!");
success = false;
}
}
Define a boolean outside of your while loop, and use it for the while's condition.
Assuming I understood your question correctly, you want to stay in the loop if the user's input threw an exception, ie it was invalid input, and you want to break out of the loop when you get valid input from the user.
boolean gotValidInput = false;
while (!gotValidInput) {
try {
System.out.println("Enter b value");
b = s.nextInt();
gotValidInput = true;
System.out.println("Sum of divison is: " + division(a,b));
} catch(ArithmeticException e) {
System.err.println("Dont divide by zero!!!");
} catch (java.util.InputMismatchException e) {
System.err.println("Enter just a Number!!!");
} finally {
System.out.println();
}
}
In this implementation, your two exceptions would both be thrown before gotValidInput = true; gets evaluated, so it would only get set to true if no exceptions were thrown.
You can put extra outter loop, like
while (true) {
System.out.println("Enter a value: ");
a = s.nextInt();
while(true) {
/// terminate the loop in case of problem with a, and allow a user to re done
}
}
Cleaned up the warnings and moved s to ouside the main method and defined it as static. It appears the s is a resource leak if within the main and is never closed.
import java.util.InputMismatchException;
import java.util.Scanner;
public class whilePerjashtim {
private static Scanner s;
public static int division(int a, int b) {
return a / b;
}
public static void main(String[] args) {
int a, b;
s = new Scanner(System.in);
System.out.println("Enter a value: ");
a = s.nextInt();
boolean input = false;
while (input == false) {
try {
System.out.println("Enter b value");
b = s.nextInt();
System.out.println("Sum of division is: " + division(a, b));
input = true;
}
catch (ArithmeticException e) {
System.err.println("Don't divide by zero!!!");
}
catch (InputMismatchException e) {
System.err.println("Enter just a Number!!!");
}
finally {
System.out.println();
}
}
}
}
You need to handle the erroneous input as well if you want the while loop to continue properly: You need to get rid of the erroneous input at the end of each catch block. Adding continue will simply make the loop run again until the user gives the correct input.
catch (InputMismatchException e)
{
System.err.println("Enter just a Number!!!");
//add this
s.nextLine();
continue;
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am very new to Java and have a question. My program is a simple guessing game with the computer. If you guess it correctly, then your points move up by 1. If you guess incorrectly, then your points decrease by 1. If you get to 7 or 0 then you win/lose. Could you help me understand why it doesnt loop back to where the while statement starts?
Thanks!
import java.util.Random;
import java.util.Scanner;
import java.lang.Math;
import java.io.*;
class RandomGame {
public static void main(String str[]) throws IOException {
Scanner scan = new Scanner(System.in);
String userAns = new String();
Random generator = new Random();
int guess, num, points = 0;
System.out.println("Hello...");
try {
Thread.sleep(1500);
} catch (InterruptedException ex) {
}
System.out.println("Would you consider playing a fun game?");
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
userAns = scan.next();
// if/else about whether they want to play the game**********
if (userAns.equals("yes")) {
System.out.println("Awww yeah lets get going!");
System.out
.println("Objective of the game:\n1.Guess numbers out of 5\n2."
+ "If you guess incorrect you get points reduced.\n3.Have fun!");
try {
Thread.sleep(5500);
} catch (InterruptedException ex) {
}
System.out.println("\nReady?");
userAns = scan.next();
if (userAns.equals("yes")) {
System.out.println("Okay! Here we go!");
// COUNTDOWN************************************
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
System.out.println("3");
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
System.out.println("2");
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
System.out.println("1");
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
// *****************************************************
System.out.println("Please enter a integer 1-5 to start the game.");
guess = scan.nextInt();
num = generator.nextInt(5) + 1;
while (points <= 7 && points >= 0)
{
if (guess == num) {
System.out.println("Correct! You gained 1 point!");
points++;
System.out.println(points);
} else if (guess != num) {
System.out.println("Incorrect. You lose 1 point.");
points--;
}
}
}
else if (userAns.equals("no")) {
System.out.println("GAMEOVER.\n\n\nHint: say \"yes\"");
}
else {
System.out.print("yes or no answers please.");
}
}
}
Your code does loop back to where the while loop starts, It just doesn't read in the next guess as your read from the users input is outside the loop. These two lines need to be inside the loop
guess = scan.nextInt();
num = generator.nextInt(5) + 1;
Currently your code reads in one int and generates one. If the guess is correct you'll get 7 points and then win, if its wrong you'll lose immediatly
If you get the answer wrong the first time, your points become -1.
while (points <= 7 && points >= 0)
Checks for ranges only between 0 and 7 and hence it quits the loop
Your while loop isn't going to wait for the nextInt(), so the loop just increments or deincrements based on what the first guess was. To fix this, wait for the next input before doing a calculation, and do the calculations within the loop:
while ((points <= 7 && points >= 0) && scan.hasNext()) {
// we have an input value
guess = scan.nextInt();
num = generator.nextInt(5) + 1;
}
take user input inside the while loop
while (points <= 7 && points >= 0)
{
guess = scan.nextInt();
num = generator.nextInt(5) + 1;
// continue
}