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;
}
Related
So, I'm getting stuck with this piece of code:
import java.util.InputMismatchException;
import java.util.Scanner;
public class ConsoleReader {
Scanner reader;
public ConsoleReader() {
reader = new Scanner(System.in);
//reader.useDelimiter(System.getProperty("line.separator"));
}
public int readInt(String msg) {
int num = 0;
boolean loop = true;
while (loop) {
try {
System.out.println(msg);
num = reader.nextInt();
loop = false;
} catch (InputMismatchException e) {
System.out.println("Invalid value!");
}
}
return num;
}
}
and here is my output:
Insert a integer number:
Invalid value!
Insert a integer number:
Invalid value!
...
As per the javadoc for Scanner:
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 that if the next token is not an int, it throws the InputMismatchException, but the token stays there. So on the next iteration of the loop, reader.nextInt() reads the same token again and throws the exception again. What you need is to use it up. Add a reader.next() inside your catch to consume the token, which is invalid and needs to be discarded.
...
} catch (InputMismatchException e) {
System.out.println("Invalid value!");
reader.next(); // this consumes the invalid token
}
What I would do is read in the whole line using Scanner.nextLine(). Then create another scanner that reads the returned string.
String line = reader.nextLine();
Scanner sc = new Scanner(line);
This would make your sample function something like this:
public int readInt(String msg) {
int num = 0;
boolean loop = true;
while (loop) {
try {
System.out.println(msg);
String line = reader.nextLine();
Scanner sc = new Scanner(line);
num = sc.nextInt();
loop = false;
} catch (InputMismatchException e) {
System.out.println("Invalid value!");
}
}
return num;
}
This way you have one scanner that gets the input and one that validates it so you don't have to worry about reader caring if they input the correct form of input.
The guard of your while-do is 'loop' variable.
The exception itself thrown before your code reaches assignment loop = false;
To be precise, the exception is thrown in previous statement which is num = reader.nextInt();
When exception thrown, value of 'loop' variable is 'true' but your code jumps to catch block and then repeats the while-do. This while-do will never stop because next iteration will throw an exception again, jumps to catch block again and so on.
To terminate this while-do, you need to guard your while-do with another logical thing such as :
Exit when reader gets non-int character
Exit when EOF
This can be done in catch block or some other lines. But precise solution depends on your specifications.
You may also try this:
public int readInt(String msg) {
int num = 0;
try {
System.out.println(msg);
num = (new Scanner(System.in)).nextInt();
} catch (InputMismatchException e) {
System.out.println("Invalid value!");
num = readInt(msg);
}
return num;
}
package nzt.nazakthul.app;
import java.util.*;
public class NztMainApp {
public static void main(String[] args) {
ReadNumber readObj = new ReadNumber();
readObj.readNumber();
}
}
class ReadNumber {
int no;
int readNumber() {
Scanner number = new Scanner(System.in);
int no=0;
boolean b=true;
do {
try {
System.out.print("Enter a number:\t");
no = number.nextInt();
} catch (InputMismatchException e) {
System.out.println("No Number");
//e.printStackTrace();
b=false;
}
}
while (b);
return no;
}
}
Personally i use BufferedReader and InputStreamReader to read String and check if is a number or not, but with scanner is less code. The code is checked and run ok.
So, I'm getting stuck with this piece of code:
import java.util.InputMismatchException;
import java.util.Scanner;
public class ConsoleReader {
Scanner reader;
public ConsoleReader() {
reader = new Scanner(System.in);
//reader.useDelimiter(System.getProperty("line.separator"));
}
public int readInt(String msg) {
int num = 0;
boolean loop = true;
while (loop) {
try {
System.out.println(msg);
num = reader.nextInt();
loop = false;
} catch (InputMismatchException e) {
System.out.println("Invalid value!");
}
}
return num;
}
}
and here is my output:
Insert a integer number:
Invalid value!
Insert a integer number:
Invalid value!
...
As per the javadoc for Scanner:
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 that if the next token is not an int, it throws the InputMismatchException, but the token stays there. So on the next iteration of the loop, reader.nextInt() reads the same token again and throws the exception again. What you need is to use it up. Add a reader.next() inside your catch to consume the token, which is invalid and needs to be discarded.
...
} catch (InputMismatchException e) {
System.out.println("Invalid value!");
reader.next(); // this consumes the invalid token
}
What I would do is read in the whole line using Scanner.nextLine(). Then create another scanner that reads the returned string.
String line = reader.nextLine();
Scanner sc = new Scanner(line);
This would make your sample function something like this:
public int readInt(String msg) {
int num = 0;
boolean loop = true;
while (loop) {
try {
System.out.println(msg);
String line = reader.nextLine();
Scanner sc = new Scanner(line);
num = sc.nextInt();
loop = false;
} catch (InputMismatchException e) {
System.out.println("Invalid value!");
}
}
return num;
}
This way you have one scanner that gets the input and one that validates it so you don't have to worry about reader caring if they input the correct form of input.
The guard of your while-do is 'loop' variable.
The exception itself thrown before your code reaches assignment loop = false;
To be precise, the exception is thrown in previous statement which is num = reader.nextInt();
When exception thrown, value of 'loop' variable is 'true' but your code jumps to catch block and then repeats the while-do. This while-do will never stop because next iteration will throw an exception again, jumps to catch block again and so on.
To terminate this while-do, you need to guard your while-do with another logical thing such as :
Exit when reader gets non-int character
Exit when EOF
This can be done in catch block or some other lines. But precise solution depends on your specifications.
You may also try this:
public int readInt(String msg) {
int num = 0;
try {
System.out.println(msg);
num = (new Scanner(System.in)).nextInt();
} catch (InputMismatchException e) {
System.out.println("Invalid value!");
num = readInt(msg);
}
return num;
}
package nzt.nazakthul.app;
import java.util.*;
public class NztMainApp {
public static void main(String[] args) {
ReadNumber readObj = new ReadNumber();
readObj.readNumber();
}
}
class ReadNumber {
int no;
int readNumber() {
Scanner number = new Scanner(System.in);
int no=0;
boolean b=true;
do {
try {
System.out.print("Enter a number:\t");
no = number.nextInt();
} catch (InputMismatchException e) {
System.out.println("No Number");
//e.printStackTrace();
b=false;
}
}
while (b);
return no;
}
}
Personally i use BufferedReader and InputStreamReader to read String and check if is a number or not, but with scanner is less code. The code is checked and run ok.
I'm attempting to create a program where the user enters a five-digit zip code from 00000 to 99999 and if the user enters a number out of that range or non-numeric values, it should throw an exception and give the user a chance to keep trying until they enter 5 numeric values.
My program only seems to catch the first instance of it, and afterwards it simply prints out the 2nd thing the user enters even if it doesn't fit the requirements.
I've just been stumped, and I'm not sure how I can use a while loop with my code, though I believe that's what I may need maybe?
I'm a beginner at this and any help would be appreciated!
import java.util.InputMismatchException;
import java.util.Scanner;
public class xzip_code {
public static void main(String[] args)
{
try
{
Bounds(Program());
}
catch(IllegalArgumentException ex)
{
System.out.println("Enter 5 Digits");
Program();
}
catch(InputMismatchException ex)
{
System.out.println("Enter Numbers");
Program();
}
}
public static void Bounds(String answer)
{
int length = answer.length();
if(length<5 || length>5)
{
throw new IllegalArgumentException("Enter 5 Digits");
}
char a = answer.charAt(0);
char b = answer.charAt(1);
char c = answer.charAt(2);
char d = answer.charAt(3);
char e = answer.charAt(4);
int f = a;
int g = b;
int h = c;
int i = d;
int j = e;
if(f>58 || g>58 || h>58|| i>58||j>58)
{
throw new InputMismatchException("Enter Numbers");
}
}
public static String Program()
{
Scanner userInput = new Scanner(System.in);
String x = userInput.next();
System.out.println(x);
return x;
}
}
Your method Bounds() does the validation work.
Currently, in your catch block you are just calling Program(). Instead you need to call the Bounds() and pass parameter Program() to it.
The below code will loop until there is no exception (successful try block execution).
boolean flag = true;
while(flag) {
try {
Bounds(Program());
flag = false;
} catch(IllegalArgumentException ex) {
System.out.println("Enter 5 Digits");
}
catch(InputMismatchException ex) {
System.out.println("Enter Numbers");
}
}
You also need to check if user has entered only numbers.
ASCII value of 0 -> 48 and 9 -> 57. Therefore, your check of > 58 makes no sense. It should check within the range.
You can simple use if (Character.isLetter(answer.charAt(index))) to check for individual digits (which is tedious).
Instead, just convert the String to Integer and check if it successfully gets converted otherwise throw error.
try {
Integer.parseInt(answer);
} catch (NumberFormatException e) {
throw new InputMismatchException("Enter Numbers");
}
You need to call Bounds(Program()); untill your program throws no error.
For that I created while loop that verifies if boolean isError is true.
To check if entered char is digit you can use Character.isDigit method.
See correct code:
package com.stackoverflow.main;
import java.util.InputMismatchException;
import java.util.Scanner;
public class xzip_code {
public static void main(String[] args) {
System.out.println("Enter 5 Digits");
boolean isError = true;
while (isError) {
try {
Bounds(Program());
} catch (IllegalArgumentException ex) {
System.out.println("Enter 5 Digits");
continue;
} catch (InputMismatchException ex) {
System.out.println("Enter Numbers");
continue;
}
isError = false;
}
}
public static void Bounds(String answer) {
int length = answer.length();
if (length < 5 || length > 5) {
throw new IllegalArgumentException("Enter 5 Digits");
}
char a = answer.charAt(0);
char b = answer.charAt(1);
char c = answer.charAt(2);
char d = answer.charAt(3);
char e = answer.charAt(4);
if (!(Character.isDigit(a) && Character.isDigit(b) && Character.isDigit(c) && Character.isDigit(d)
&& Character.isDigit(e))) {
throw new InputMismatchException("Enter Numbers");
}
}
public static String Program() {
Scanner userInput = new Scanner(System.in);
String x = userInput.next();
System.out.println(x);
return x;
}
}
Prints:
Enter 5 Digits
ewewdsddd
ewewdsddd
Enter 5 Digits
dffdffg
dffdffg
Enter 5 Digits
443446665
443446665
Enter 5 Digits
4444q
4444q
Enter Numbers
33333
33333
You need to make your catch a recursive call. The way you wrote it, it is caught, tries again, then ends.
Try to do it like this.
void foo() {
try {
bar();
} catch (Exception e) {
// try again
foo();
}
}
It also may be a good idea to keep track of how many times you retry. This could easily cause a StackOverflowError if you get it wrong too many times. I want to say the number is about 8 or 9 thousand.
Another option would be to use a loop.
void foo() {
boolean success = false;
while(!success) {
success = tryFoo();
}
}
boolean tryFoo() {
try {
bar();
return true; // true for success
} catch (Exception e) {
return false; // false for failed
}
}
There are several questions I would like to ask, please refer the comment part I have added in the code, Thanks.
package test;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Test {
/* Task:
prompt user to read two integers and display the sum. prompt user to read the number again if the input is incorrect */
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean accept_a = false;
boolean accept_b = false;
int a;
int b;
while (accept_a == false) {
try {
System.out.print("Input A: ");
a = input.nextInt(); /* 1. Let's enter "abc" to trigger the exception handling part first*/
accept_a = true;
} catch (InputMismatchException ex) {
System.out.println("Input is Wrong");
input.nextLine(); /* 2. I am still not familiar with nextLine() parameter after reading the java manual, would you mind to explain more? All I want to do is "Clear Scanner Buffer" so it wont loop for the println and ask user to input A again, is it a correct way to do it? */
}
}
while (accept_b == false) {
try {
System.out.print("Input B: ");
b = input.nextInt();
accept_b = true;
} catch (InputMismatchException ex) { /*3. Since this is similar to the above situation, is it possible to reuse the try-catch block to handling b (or even more input like c d e...) exception? */
System.out.println("Input is Wrong");
input.nextLine();
}
}
System.out.println("The sum is " + (a + b)); /* 4. Why a & b is not found?*/
}
}
I am still not familiar with nextLine() parameter after reading the java manual, would you mind to explain more? All I want to do is "Clear Scanner Buffer" so it wont loop for the println and ask user to input A again, is it a correct way to do it?
The use of input.nextLine(); after input.nextInt(); is to clear the remaining content from the input stream, as (at least) the new line character is still in the buffer, leaving the contents in the buffer will cause input.nextInt(); to continue throwing an Exception if it's no cleared first
Since this is similar to the above situation, is it possible to reuse the try-catch block to handling b (or even more input like c d e...) exception?
You could, but what happens if input b is wrong? Do you ask the user to re-enter input a? What happens if you have 100 inputs and they get the last one wrong?You'd actually be better off writing a method which did this for, that is, one which prompted the user for a value and returned that value
For example...
public int promptForIntValue(String prompt) {
int value = -1;
boolean accepted = false;
do {
try {
System.out.print(prompt);
value = input.nextInt();
accepted = true;
} catch (InputMismatchException ex) {
System.out.println("Input is Wrong");
input.nextLine();
}
} while (!accepted);
return value;
}
Why a & b is not found?
Because they've not been initialised and the compiler can not be sure that they have a valid value...
Try changing it something more like.
int a = 0;
int b = 0;
Yes, it's okay. And will consume the non-integer input.
Yes. If we extract it to a method.
Because the compiler believes they might not be initialized.
Let's simplify and extract a method,
private static int readInt(String name, Scanner input) {
while (true) {
try {
System.out.printf("Input %s: ", name);
return input.nextInt();
} catch (InputMismatchException ex) {
System.out.printf("Input %s is Wrong%n", input.nextLine());
}
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int a = readInt("A", input);
int b = readInt("B", input);
System.out.println("The sum is " + (a + b));
}
I have put comment to that question line.
package test;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean accept_a = false;
boolean accept_b = false;
int a=0;
int b=0;
System.out.print("Input A: ");
while (accept_a == false) {
try {
a = input.nextInt(); // it looks for integer token otherwise exception
accept_a = true;
} catch (InputMismatchException ex) {
System.out.println("Input is Wrong");
input.next(); // Move to next other wise exception // you can use hasNextInt()
}
}
System.out.print("Input B: ");
while (accept_b == false) {
try {
b = input.nextInt();
accept_b = true;
} catch (InputMismatchException ex) {
System.out.println("Input is Wrong");
input.next();
}
}
System.out.println("The sum is " + (a + b)); // complier doesn't know wheather they have initialised or not because of try-catch blocks. so explicitly initialised them.
}
}
Check out this "nextLine() after nextInt()"
and initialize the variable a and b to zero
nextInt() method does not read the last newline character.
I'm still in the learning part of Java. I've made a kind of guessing game. It looks like this:
import java.util.Scanner;
import java.util.Random;
public class guessing_game {
static Scanner input = new Scanner(System.in);
static Random generator = new Random();
public static void main(String[] args) {
int number;
number = generator.nextInt(20);
System.out.println("Guess the number!");
game(number);
}
public static void game(int number) {
int inputStorage;
inputStorage = input.nextInt();
if (inputStorage == number) {
System.out.println("You've guessed the right number!");
}
else if (inputStorage != number) {
System.out.println("Wrong number, try again!");
game(number);
}
}
}
Now I have a problem. My little sister and I played this "game". My sister was typing on the numpad. She accidently hit the + button before pressing enter and I got some errors. My question is: How can I let my application print a line which is saying that you can only input numbers and then restarts the game stub again?
One way would be to wrap the input.nextInt() in a try catch statement and catch the exceptions that are thrown by input.nextInt(), InputMismatchException. A good tutorial for try catch statements is here if you aren't sure what I am talking about.
try {
inputStorage = input.nextInt();
} catch (InputMismatchException e){
System.out.println("invalid type");
}
Another way you can do this is:
if(input.hasNextInt()){
inputStorage = input.nextInt();
}else{
System.out.println("invalid type");
}
There is also an error with continuing the game try using a while loop with a break if the number was guessed correctly:
int inputStorage;
boolean notGuessed = true;
while(notGuessed)
{
if(input.hasNextInt()){
inputStorage = input.nextInt();
} else{
System.out.println("invalid type");
}
if (inputStorage == number) {
System.out.println("You've guessed the right number!");
notGuessed = false;
}
else if (inputStorage != number) {
System.out.println("Wrong number, try again!");
}
}
Well this is quite easy. You can accomplish it in various way.
Try this one
public static int checkInt(String strNumber) {
int Number;
try {
Number = Integer.parseInt(strNumber);
} catch (NumberFormatException ex) {
Number = -1;
}
return Number;
}
Or even simpler:
public static int checkInt(String strNumber) {
Number = Integer.parseInt(strNumber, -1);
return Number;
}
The second one is even simpler because you omit a try catch block, that is rather not correctly used in such case. Read about the functions of Integer class.
You can use a try/catch:
boolean b = true;
while (b) {
try {
inputStorage = input.nextInt();
b= false;
} catch (InputMismatchException e) {
System.out.println("Invalid input. Please enter again!");
}
}
Since the error you got was an Exceptiion: InputMismatchException.
You can explicitly handle the exception using the Exception handling mechanism in java.
Read this
Read this
to know how it actually works.
Above suggested answers are exception handling only.