Mikaela Clarice
Mikaela Clarice

Reputation: 3

JAVA: Problems with Exception-Handling? Program only catches Exception once

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;

}

}

Upvotes: 0

Views: 77

Answers (3)

Devendra Lattu
Devendra Lattu

Reputation: 2802

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");
}

Upvotes: 1

Jay Smith
Jay Smith

Reputation: 2480

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

Upvotes: 0

mattmess1221
mattmess1221

Reputation: 4434

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
    }
}

Upvotes: 0

Related Questions