Are there a way of preventing automatic exception handling? - java

If the user enter a non-numeric value for example "Hello", I want to give the user a new chance to enter a numeric value until he succeeds.
Running the code below, the text "This is not a numeric value. Enter a numeric value: ", will show in the console, if the user enters a non-numeric value. However, the user will not be able to enter a new value. Because the error message "Exception in thread..." will show and stop the program.
How do I solve this?
Edit!
New code (This code works, except it stops the program completely. Every method called afterwards, won't run.) Edit2! It did not work!
int number;
do {
try {
System.out.println("Enter a numeric value: ");
number = Integer.parseInt(s.nextLine());
if (s.nextInt() != (int)number) {
throw new NumberFormatException();
}
break;
}
catch (NumberFormatException e) {
System.out.println("This is not a numeric value. Enter a numeric value: ");
}
} while (true)
Old code
int number;
try {
Scanner s = new Scanner(System.in);
System.out.println("Enter a numeric value: ");
number = s.nextInt();
if (number != (int)number) {
throw new Exception();
}
}
catch(Exception e) {
do {
System.out.println("This is not a numeric value. Enter a numeric value: ");
number = s.nextInt();
} while (number != (int)number);
}

Use NumberFormatException instead of Base Exception Class
int number;
Scanner s = new Scanner(System.in);
System.out.println("Enter a numeric value: ");
do {
try {
number = Integer.parseInt(s.nextLine());
//Do your work
break;
} catch (NumberFormatException e) {
System.out.println("This is not a numeric value. Enter a numeric value: ");
}
}
while (true);
}

Please try below given code:
int number;
Scanner s = new Scanner (System.in);
System.out.println ("Enter a numeric value: ");
do
{
try
{
number = Integer.parseInt (s.nextLine ());
//Do your work
break;
}
catch (Exception e)
{
System.out.println
("This is not a numeric value. Enter a numeric value: ");
}
}
while (true);
}

It sounds like you want to loop forever until the user enters a valid integer. A common way to express "loop forever" is with while (true) {...}. This is an "infinite loop." The only way to exit this loop is with a break statement or a return statement (or by throwing an exception, but in this case you want to catch the exception and continue looping).
One problem with using scanner.nextInt() is that if the value is not an integer, the value will remain in the scanner's buffer. If you keep calling nextInt(), you'll just keep getting InputMismatchExceptions since the scanner will keep trying to interpret the same bad input as an integer, over and over again.
One way around that problem is to use scanner.nextLine() to read the value as a String, and then use Integer.parseInt(String) to convert the String to an int. If the conversion fails, Integer.parseInt(String) throws a NumberFormatException. You can handle this exception by catching it.
Here's a little function that loops forever until the user enters a value that can be parsed as an int:
public static int promptForInt(Scanner scanner) {
while (true) {
System.out.println("Enter a numeric value:");
try {
return Integer.parseInt(scanner.nextLine());
} catch (NumberFormatException e) {
System.out.print("This is not a numeric value. ");
}
}
}
You can call the method like this:
Scanner scanner = new Scanner(System.in);
int number = promptForInt(scanner);

I don't think you truly understand where the exception is coming from. The line throw new Exception(); never runs in your code. This is because your if statement says if (number != (int) number), which will never be true because the variable number is already of the type int, so you are basically saying if (number != number), which can never be true. If you take a look at Scanner's nextInt() method, you'll notice that it actually throws InputMismatchException. That is the exception you are catching with your try-catch, but it is not the exception that is causing the error message. So where is that exception coming from? The line number = s.nextInt(); is not compilable code. You defined s inside the try block, so therefore s only exists inside the try block. You get an exception when you try to access it in the catch block because s is not a variable there; it does not exist as far as the compiler is concerned. The fix is pretty simple; just move the declaration for s to outside the try block, and put the while loop around the try-catch block. Also remember to consume the line separators in the input stream using s.nextLine() every time you try to read an int. Here's an example of how I would do it:
int number;
Scanner s = new Scanner(System.in); //declare s outside of the try block
System.out.println("Enter a numeric value: ");
while (true) { //while loop goes around the try-catch block
try {
number = s.nextInt(); //this could throw InputMismatchException
break; //if no exception is thrown, break out of the loop
} catch (InputMismatchException e) { //if the exception is thrown
s.nextLine(); //consume the line separator character(s)
System.out.println("This is not a numeric value. Enter a numeric value: "); //prompt the user for another value
//this will then go back to the top of the try block again, because we never broke out of the while loop
}
}
s.nextLine(); //consume the line separator character(s)

Try the following, if you take your input as a string you can parseInt to check if its an integer value
String number = null;
Scanner s = new Scanner(System.in);
System.out.println("Enter a numeric value: ");
number = s.next();
try {
// checking valid integer using parseInt() method
Integer.parseInt(number);
} catch (NumberFormatException e) {
System.out.println("This is not a numeric value. Enter a numeric value:");
number = s.next();
// put this line here to prove it accepted the second attempt
System.out.println("Your entered integer is:" + number);
}
s.close();
}
}

Related

Im trying to add a try catch that tells the user they cant plug in negative numbers

I was able to add a try catch that tells the user that they cant use
letters.However for some reason adding a try catch for negative numbers dosent seem to work.I know that the try block is where if somthing can go wrong like entering in a negative number the catch can print out the error message. I think thats where my problem lies. Another problem that is associated with the try catch is that I'm use to the user entering in -1 to enter the contents that the user inputs so I'm thinking its gonna cause a logical problem.
tl;dr Adding a try catch or another catch to prevent user from adding negative numbers
this is not the the whole program but what it does is that it filters out the integers that the user inputs and separates the evens and odds.
public static void main(String [] args)
{
Scanner stdin = new Scanner(System.in);//for user input
int[] evenNum = new int [100];//Even Array up too 100
int[] oddNum = new int[100];//Odd Array up too 100
int evenIndex=0;//even numbers
int input=0;//user input
int i=0;//incrementer for arrays
int k=0;
int j=0;
String name;
System.out.println("Type In Your Name");//Type in name
name = stdin.nextLine();
while ((i < oddNum.length && i < evenNum.length) && input !=-1)//100 numbers only
{
try{//this is what we want anything else the catch will block it and display a message
System.out.println(name+" Enter a positive number, Enter -1 For results");
input= stdin.nextInt();
oddNum[i]=input;//holds input
i++;//Increments array
}
catch(Exception d){
System.out.println("Only Positive Numbers & no Letters Please!");
stdin.next();
}
}
You can check the input variable after you get it from the scanner
if (input < 0) {
System.out.println("Only Positive Numbers & no Letters Please!");
}
Your code does not throw any Exception when the number is read from the scanner. So you cannot expect that the execution jumps into the catch-block when you enter a negative number.
But you can alternatively throw an exception when the input is negative. This will make the thread to jump directly into the catch-block. In the catch-block you can then print the message you passed the IllegalArgumentException
if (input < 0) {
// this gets caught in the catch block
throw new IllegalArgumentException("Only Positive Numbers & no Letters Please!");
}
...
} catch (IllegarArgumentException e) {
System.out.println(e.getMessage());
}
It is generally bad practice to catch Exception (java.lang.Exception). This is the "root" of all checked exceptions and the catch-block will be jumped into whenever any subclass of Exception is thrown.
Just catch the concrete exception that you are expecting. (In this case IllegalArgumentException.)
Also you should not use exceptions to control the execution flow of your program.
I would suggest something like this:
do {
System.out.println(name+" Enter a positive number, Enter -1 For results");
try {
input = stdin.nextInt();
} catch (java.util.InputMismatchException e) { // if the user enters something that is not an integer
System.out.println("Please only enter integers");
input = Integer.MIN_VALUE;
stdin.next(); // consume the non-int so we don't get caught in an endless loop
}
} while (input < -1); // loop as long as the input is less than -1
if (input == -1) {
// show the results here
}
This will accept positive integers and will prompt for an input until the user enters a positive number, 0 (zero) or -1 (which should show the results)
You can do it like this:
if (input < 0) {
throw new IllegalArgumentException();
}
Now if the number is negative, it will throw exception and the catch code can be executed. Because you catch Exception so all of the exception will be catches here.
Note: In catch block you no need to add stdin.next(); because the program will continue from the first line of while loop.
In order for your catch block to catch exception, the Exception needs to be thrown from the code. In case of negative numbers the line input= stdin.nextInt(); will not throw exception as it is perfectly legal for integer to be negative. You will need to add if condition like this:
input = stdin.nextInt();
if ( input < 0 ) {
throw new Exception("Negative number entered");
}
But some consider this to be bad practice because you are using exceptions to control the flow of a program. So I give you another example how you can do this without throwing an exception:
input = stdin.nextInt();
if ( input < 0 ) {
System.out.println("Only Positive Numbers Please");
continue; // will continue from the beginning of a loop
}

How to handle exception in case of string

I am getting an error when I am entering string value in integer variable. I want to know to handle the exception, as my program give a indication that enter your value again rather it stop and gave exceptional handling error.
System.out.println("Please enter a number");
Scanner obj1=new Scanner(System.in);
int a=obj1.nextInt(); //I am entering string value here
System.out.println(a);
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at javaapplication13.JavaApplication13.main(JavaApplication13.java:23)
It is better to preventing throwing exception instead of handling it since creating exception object may be quite expensive. In case of Scanner class your code can look like:
Scanner scanner = new Scanner(System.in);
System.out.println("Please enter a number:");
while(!scanner.hasNextInt()){//while user is not providing valid int
//inform him about it
System.out.println("that was not valid integer, please try again: ");
//and consume invalid value (maybe even entire line)
scanner.nextLine();
}
//since we are out of loop it must mean that user entered valid int, lets store it
int a = scanner.nextInt();
System.out.println(a);
You can also wrap this code in some nice utility method in which you can even add support to maximal number of tries. For that kind of code you can use as result Optional<Integer>. This will allow us clear info if user
provided proper value, and we will return Optional with this value
or if he failed to do so, in which case we can return empty Optional.
which is cleanest way of handling results which may not exist.
Without Optional we would either have to:
return some default value like:
-1 but in that case we don't know if -1 represents invalid input, or if user actually provided -1 which means it may be proper result
null (if we change return type to Integer) but this way we are making our programmer who will use our method to also check if(result != null) which may not be that obvious for many programmers (using Optional gives us clear idea that result may not exist so programmer knows that he should check this possibility).
throw exception, but since reason why we are creating our method is to avoid creating and handling exception it would be kind of stupid.
So your method can look like
//-1 represents infinite number of tries
public static Optional<Integer> readInt(Scanner sc, String msg, int tries){
System.out.println(msg);
int counter = 0;
//while user still has more tries but is providing invalid int
while((tries == -1 || counter < tries) && !sc.hasNextInt()){
//inform him about wrong data
if (tries == -1 || ++counter < tries)
System.out.println("That was not valid integer. Please try again:");
else
System.out.println("That was not valid integer.");
//and consume invalid value (maybe even entire line)
sc.nextLine();
}
// since we are out of loop it must mean that user entered valid int
// or run out of tries
if (tries == -1 || counter < tries)
return Optional.of(sc.nextInt());
else
return Optional.empty();
}
and its usage can look like
Scanner scanner = new Scanner(System.in);
Optional<Integer> result = readInt(scanner, "Please enter a number:", 1);
if(result.isPresent()){
System.out.println(result.get());
}else{
System.out.println("User failed to give valid integer. Program will terminate");
}
Use this
System.out.println("Please enter a number");
Scanner obj1=new Scanner(System.in);
if(obj1.hasNextInt())
{
int a=obj1.nextInt(); //I am entering string value here
System.out.println(a);
}
Put the code in the try-catch block to handle the InputMismatchException
System.out.println("Please enter a number");
Scanner obj1=new Scanner(System.in);
try {
int a=obj1.nextInt();
}
catch(InputMismatchException ime) {
/*show error message for incorrect input*/
}
catch(Exception e) {
/*Show error message*/
}
System.out.println(a);
Hope, this solves the problem.
You can try this...
boolean i=true;
while(i){
try{
System.out.println("Please enter a number");
Scanner obj1=new Scanner(System.in);
int a=obj1.nextInt(); //I am entering string value here
System.out.println(a);
i=false;
}catch(InputMismatchException e){
System.out.println("Invalid number, please enter again");
}
}

Can i use Scanner within a catch statement [duplicate]

This question already has answers here:
try/catch with InputMismatchException creates infinite loop [duplicate]
(7 answers)
Closed 7 years ago.
If I type in letter for the first Scanner statement i get "error!!" and "enter a number" but cannot input another number.I am a beginner and do not know whether an input statement can be used within a catch statement
import java.util.InputMismatchException;
import java.util.Scanner;
public class excep {
public static void main(String args[]){
int n;
Scanner input=new Scanner(System.in);
try{
System.out.println("ENTER A NUMBER: ");
n=input.nextInt();
}
catch(InputMismatchException e){
System.out.println("ERROR!!! \nENTER A NUMBER :");
n=input.nextInt();
}
}
}
You must have to eat or remove characters from the buffer before you restart input. For the sake of simplicity, your code should look alike :
while(true) {
Scanner input=new Scanner(System.in);
try {
System.out.println("ENTER A NUMBER: ");
n=input.nextInt();
break;
}catch(InputMismatchException e) {
System.out.println("ERROR!!! \nENTER A NUMBER :");
input.next(); // eat some chars
}
}
The biggest problem with your approach is that if nextInt() fails because the user did not enter a valid integer, the scanner does not advance. The scanner has a pointer that points to the next character to read from the input. When you use nextInt(), if the next "token" is an integer, the scanner will advance the pointer past the integer. But if it isn't an integer, an exception is thrown--and the pointer stays in the same place as before. So when you catch the exception, then call nextInt(), the scanner tries to read the same invalid integer that it just tried to read last time.
To skip over the bad integer, you can say input.next() to skip over one token, or input.nextLine() to skip over the entire remainder of the input line, before trying to read another integer. (Both of these return String results, but you can discard the result since it's not important to you).
However, this is not really a good way to use try/catch. If the user is having a bad day and enters another invalid integer, the scanner will throw an exception, and it will not be caught, since you are not in the try when the second exception is thrown. catch doesn't loop back and catch it again. The best idiom for this is a loop:
boolean validIntegerEntered = false;
System.out.println("ENTER A NUMBER: ");
while (!validIntegerEntered) {
try {
n=input.nextInt();
validIntegerEntered = true; // will not get here if nextInt()
// throws an exception
}
catch (InputMismatchException e) {
input.nextLine(); // let the scanner skip over the bad input
System.out.println("ERROR!!! \nENTER A NUMBER :");
// don't call nextInt() here; loop back, and nextInt() will be called
// in the try statement
}
}
Syntactically, Yes you can but you shouldn't use it. Why?
input.nextInt(); can throw InputMismatchException or NoSuchElementException or IllegalStateException if the scanner is closed.
If any of those exceptions occur within the catch block, you are not handling them. You should probably look at how to implement a retry catch
You are using the input.nextInt(), means it can only accepts int values.If you want to enter string values then better to use input.nextine().
In your code in catch block you are using again input.nextInt() but scanner has already wrong input in it that why it throw the exception.If you want to take input inside catch block then try the below code:
catch(InputMismatchException e){
System.out.println("ERROR!!! \nENTER A NUMBER :");
Scanner input1=new Scanner(System.in);
n=input1.nextInt();
System.out.println("Inside catch:"+n);
}

Scanner - java.util.NoSuchElementException

Does anyone see a problem with this? First input works fine, but after the first loop, it doesn't ask to enter a value again. How do I fix this?
int value;
while(true)
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter a value");
try
{
value = scan.nextInt();
System.out.println("value provided is: " + value);
scan.nextLine(); // consumes "\n" character in buffer
}
catch(InputMismatchException e) // outputs error message if value provided is not an integer
{
System.out.println("Incorrect input type. Try again.");
continue; // restarts while loop to allow for re-entering of a valid input
}
scan.close();
}
Move scan.close(); to outside the while loop.
Also you don't have to construct a new Scanner on each iteration. Move the declaration to outside the loop as well.
When close the Scanner, this closes the System.in input stream.
So now when you try to instantiate it again, it doesn't find any opened stream and you'll get that exception.
At the end of the while loop you have written scan.close(). This will close the scanner preventing any further scans. Removing that statement would ensure your while loop keeps asking you for the number(will be an infinite loop in your case)
Also, scan.nextInt() in effect ignores all new line and waits till you actually input a number and hit enter. So, scan.nextLine() can be omitted. You need that only in case where you use scan.nextLine() to fetch the value entered. In that case, the new line character is also read as an input, as a result of which you need an extra nextLine() call to consume it.
When you do scan.close(), it closes the underlying System.in stream. So in the next iteration it will not have anything to read.
For example:
import java.io.IOException;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int value;
while (true) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter a value");
try {
value = scan.nextInt();
System.out.println("value provided is: " + value);
scan.nextLine(); // consumes "\n" character in buffer
} catch (InputMismatchException e) // outputs error message if value
// provided is not an integer
{
System.out.println("Incorrect input type. Try again.");
continue; // restarts while loop to allow for re-entering of a
// valid input
}
scan.close();
try {
int x = System.in.read();
System.out.println(x);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
OUTPUT:
Enter a value
10
value provided is: 10
Enter a value
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:162)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:206)
at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
at Main.main(Main.java:24)
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:907)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextInt(Scanner.java:2160)
at java.util.Scanner.nextInt(Scanner.java:2119)
at Main.main(Main.java:12)
Check this question for more:
Is it safe not to close a Java Scanner, provided I close the underlying readable?

scanner.nextInt(), out of range avoidance?

I've finished a simple program that converts a decimal number to binary (32bit). I would like to implement some type of error message should the user enter in an overflow number (anything over 2147483647). I tried a if_else , loop, but quickly found out I couldn't even do that. So I messed with taking the input as a string, and then using some things like .valueOF() etc, and still can't seem to get around to the solution.
I don't see how I can compare any value to a >2147483648 if I can't store the value in the first place.
Here's the bare code I have for the getDecimal() method:
numberIn = scan.nextInt();
Edit:: After trying the try / catch method, running into a compile error of
"non-static method nextInt() cannot be referenced from a static context".
My code is below.
public void getDec()
{
System.out.println("\nPlease enter the number to wish to convert: ");
try{
numberIn = Scanner.nextInt();
}
catch (InputMismatchException e){
System.out.println("Invalid Input for a Decimal Value");
}
}
You can use Scanner.hasNextInt() method, which returns false, if the next token cannot be converted to an int. Then in the else block, you can read the input as string using Scanner.nextLine() and print it with an appropriate error message. Personally, I prefer this method :
if (scanner.hasNextInt()) {
a = scanner.nextInt();
} else {
// Can't read the input as int.
// Read it rather as String, and display the error message
String str = scanner.nextLine();
System.out.println(String.format("Invalid input: %s cannot be converted to an int.", str));
}
Another way to achieve this is of course, using try-catch block. Scanner#nextInt() method throws an InputMismatchException, when it can't convert the given input into an integer. So, you just need to handle InputMismatchException: -
try {
int a = scan.nextInt();
} catch (InputMismatchException e) {
System.out.println("Invalid argument for an int");
}
I suggest you surround that statement with a try/catch block for NumberFormatException.
Like so:
try {
numberIn = Integer.valueOf(scan.next());
}catch(NumberFormatException ex) {
System.out.println("Could not parse integer or integer out of range!");
}
use exceptions.. whenever a number is entered more than its storing capacity then exception will be raised
Refer docs.oracle.com/javase/tutorial/essential/exceptions/
You can user hasNextInt() method to make sure that there is an integer ready to be read.
try this :
long num=(long)scan.nextLong();
if (num > Integer.MAX_VALUE){
print error.
}
else
int x=(int)num;
or try catch:
try{
int number=scan.nextInt()
}
}catch(Exception ex){
print the error
}

Categories