David Conrod
David Conrod

Reputation: 1

How to keep my code running after an exception is caught (Java)

I'm trying to write code for a class project that can handle all exceptions and invalid entries from the user.

import java.util.Scanner;

public class Paint1 {

public static void main(String[] args) {
    Scanner scnr = new Scanner(System.in);
    double wallHeight = 0.0;
    double wallWidth = 0.0;
    double wallArea = 0.0;
    double gallonsPaintNeeded = 0.0;

    final double squareFeetPerGallons = 350.0;

    // Implement a do-while loop to ensure input is valid
    // Prompt user to input wall's height
    try {
        //System.out.println("Enter wall height (feet): ");
        do {//wallHeight = scnr.nextDouble();
            System.out.println("Enter wall height (feet): ");
            wallHeight = scnr.nextDouble();
            if (wallHeight <= 0) {
                System.out.println("Invalid height");
            }
        } while (wallHeight <= 0);
    } catch (Exception excpt) {
        System.out.println("Invalid height");
        wallHeight = scnr.nextDouble();
    }

    // Implement a do-while loop to ensure input is valid
    // Prompt user to input wall's width
    do {
        System.out.println("Enter wall width (feet): ");
        wallWidth = scnr.nextDouble();
        if (wallWidth <= 0) {
            System.out.println("Invalid Width");
        }
    } while (wallWidth <= 0);


    // Calculate and output wall area
    wallArea = wallHeight * wallWidth;
    System.out.println("Wall area:  " + wallArea + " square feet");

    // Calculate and output the amount of paint (in gallons) needed to paint the wall
    gallonsPaintNeeded = wallArea/squareFeetPerGallons;
    System.out.println("Paint needed: " + gallonsPaintNeeded + " gallons");

}
}

The check that I'm trying to pass for the assignment is inputting a string instead of a double for the wallHeight. It prints "Invalid height" but then the program stops running and returns the error. How do I get it to continue running and prompt again for a valid input from the user?

Upvotes: 0

Views: 4403

Answers (4)

Independent Analysis
Independent Analysis

Reputation: 11

import java.util.Scanner;

public class Paint1 {

    public static void main(String[] args) {
        Scanner scnr = new Scanner(System.in);
        double wallHeight = 0.0;
        double wallWidth = 0.0;
        double wallArea = 0.0;
        double gallonsPaintNeeded = 0.0;
        boolean validNumber = false;
        
        final double squareFeetPerGallons = 350.0;
        
        // Implement a do-while loop to ensure input is valid
        // Prompt user to input wall's height
        do {
        System.out.println("Enter wall height (feet): ");
        if (scnr.hasNextDouble()) {
            wallHeight = scnr.nextDouble();
            validNumber = true;
            if (wallHeight >0) {
                wallHeight = wallHeight;
            } else {
                System.out.println("Must be greater than 0.  Try again.");
                validNumber = false;
            }
        } else {
            System.out.println("Invalid input.  Try again.");
            System.out.println();
            validNumber = false;
            scnr.next();
        } 
        } while (!validNumber);
        
        

        // Implement a do-while loop to ensure input is valid
        // Implement if-else loops to ensure correct value/type is given
        // Prompt user to input wall's width
        validNumber = false;
        do {
            System.out.println("Enter wall width (feet): ");
            if (scnr.hasNextDouble()) { 
                wallWidth = scnr.nextDouble();  
                validNumber = true;
                if (wallWidth >0) {  
                    wallWidth = wallWidth;
                } else {
                    System.out.println("Must be greater than 0.  Try again.");
                    validNumber = false;
                }
            } else {
                System.out.println("Invalid input.  Try again.");
                System.out.println();
                validNumber = false;
                scnr.next();
            }    
        } while (!validNumber); 

        // Calculate and output wall area
        wallArea = wallHeight * wallWidth;
        System.out.println("Wall area: " + wallArea + " square feet");

        // Calculate and output the amount of paint (in gallons) needed to paint the wall
        gallonsPaintNeeded = wallArea/squareFeetPerGallons;
        System.out.println("Paint needed: " + gallonsPaintNeeded + " gallons");

    }
}

Upvotes: 1

Petr Bodn&#225;r
Petr Bodn&#225;r

Reputation: 558

Here is a working variant based on your code, with fixes and explanations:

    // Implement a do-while loop to ensure input is valid
    // Prompt user to input wall's height
    do { // moved one level up <- enable repeated input until it is valid
        try { // moved one level down <- catch exception where it occurs
            System.out.println("Enter wall height (feet): ");
            wallHeight = scnr.nextDouble();
            if (wallHeight <= 0) {
                System.out.println("Invalid height");
            }
        } catch (Exception excpt) { // generally better: InputMismatchException
            System.out.println("Invalid height");
            scnr.nextLine(); // SKIP THIS INVALID LINE.
            // Otherwise calling nextDouble() only throws the same exception as previously.
        }
    } while (wallHeight <= 0);

Note that this should meet the OP. Otherwise:

  • If you may introduce new methods in your class project, then extracting the do - while to a dedicated method for reading any number input should be the way to go.
  • If you would like to avoid handling exceptions, you could use a combination of scnr.hasNextDouble() + scnr.nextLine() instead. You can read the methods' javadoc to fully understand what they do.

Upvotes: 0

Elliott Frisch
Elliott Frisch

Reputation: 201409

Your current method of prompting for input (on wallWidth and wallHeight) is flawed because you catch an exception which is almost certainly InputMismatchException (and then you fail to consume the token that was not a number). I would strongly recommend you extract your prompt to another method; something like

private static double readWallDimension(Scanner scnr, String dimension) {
    for (;;) {
        try {
            System.out.printf("Enter wall %s (feet):%n", dimension);
            double dim = scnr.nextDouble();
            if (dim <= 0) {
                System.out.printf("Invalid %s%n", dimension);
            } else {
                return dim;
            }
        } catch (InputMismatchException excpt) {
            System.out.printf("Invalid %s%n", dimension);
            scnr.nextLine();
        }
    }
}

Then your main method is significantly simpler, invoking that method twice (and both times the exceptions are handled locally).

public static void main(String[] args) {
    Scanner scnr = new Scanner(System.in);
    final double squareFeetPerGallons = 350.0;

    double wallHeight = readWallDimension(scnr, "height");
    double wallWidth = readWallDimension(scnr, "width");

    // Calculate and output wall area
    double wallArea = wallHeight * wallWidth;
    System.out.println("Wall area:  " + wallArea + " square feet");

    // Calculate and output the amount of paint (in gallons) needed to paint the
    // wall
    double gallonsPaintNeeded = wallArea / squareFeetPerGallons;
    System.out.println("Paint needed: " + gallonsPaintNeeded + " gallons");
}

Upvotes: 0

Saurabh
Saurabh

Reputation: 11

if (in.hasNextDouble()) {
        double a = in.hasNextDouble() ; 
        System.out.println(a);
    } else {
        System.out.println("Invalid input");
    }

This prevents InputMismatchException from even being thrown, because you always make sure that it WILL match before you read it.

Upvotes: 0

Related Questions