1

Below is my code, I want to add a try/catch block within the do/while loop in order to throw exceptions for user input other than numbers (i.e. if the user enters twenty instead of 20). I am unsure how to write the comparison to throw the exception.

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;

        double squareFeetPerGallons = 350.0;

        // Prompt user to input wall's height
        System.out.println("Enter wall height (feet): ");
        wallHeight = scnr.nextDouble();
        while (wallHeight <= 0) {
            do {
                System.out.println("Wall height must be a number greater then zero and in arabic numeral format.");
                System.out.println("Enter wall height (feet): ");
                wallHeight = scnr.nextDouble();
            } while (wallHeight <= 0);
        }

        // Prompt user to input wall's width
        System.out.println("Enter wall width (feet): ");
        wallWidth = scnr.nextDouble();
        while (wallWidth <= 0) {
            do {
                System.out.println("Wall width must be a number greater then zero and in arabic numeral format.");
                System.out.println("Enter wall width (feet): ");
                wallWidth = scnr.nextDouble();
            } 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");
    }
}
Oliver D
  • 2,579
  • 6
  • 37
  • 80

1 Answers1

1

Initialize the vars so that if the catch block gets executed it will continue asking for the number and show the error message in the catch block:

wallHeight = 0;
do {
    try {
        // Prompt user to input wall's height
        System.out.println("Enter wall height (feet): ");
        String input = scnr.next();
        wallHeight = Double.parseDouble(input);
    } catch (Exception e) {
        System.out.println("Wall height must be a number greater then zero and in arabic numeral format.");
    }
} while (wallHeight <= 0);

wallWidth = 0;
do {
    try{
        // Prompt user to input wall's width
        System.out.println("Enter wall width (feet): ");
        String input = scnr.next();
        wallWidth = Double.parseDouble(input);
    } catch (Exception e) {
        System.out.println("Wall width must be a number greater then zero and in arabic numeral format.");
    }
} while (wallWidth <= 0);

Another thing I do is as the input data can be different than a double you can read it as string so that it gets consumed and then parse it and catch the exception of this, otherwise the wrong input will still be there and will cause an infinite loop.

Another possibility is to use scnr.nextLine() to consume the input in the catch block like in:

try {
    // Prompt user to input wall's height
    System.out.println("Enter wall height (feet): ");
    wallHeight = scnr.nextDouble();
} catch (Exception e) {
    System.out.println("Wall height must be a number greater then zero and in arabic numeral format.");
    scnr.nextLine();
}

And notice you can get rid of the other while, you just need one, in this case I've used the do/while.

jeprubio
  • 17,312
  • 5
  • 45
  • 56
  • Appreciate the help! That definitely catches the exception but I have a new issue now. With bad user input it goes into an infinite loop without stopping to allow for new user input. –  Apr 11 '20 at 14:18
  • Double checked the code but still the same issue. Bad user input loops back and executes the "try" section but doesn't wait for input before executing the "catch". –  Apr 11 '20 at 14:30
  • Yes, sorry, my mistake. In this cases what I do is to get the input as `String` and then use `Float.parseFloat` and catch the exception of this. This way the input gets consumed each time no mater whether it has the expected value or not as its waiting for a string. Check now – jeprubio Apr 11 '20 at 14:39
  • That fixed it. Thanks again! Any idea why it went into that loop? I'd love to figure that out. It looked as though something was causing it to execute the catch every time instead of waiting for user input. –  Apr 11 '20 at 14:45
  • That happens because `scnr.nextDouble` is waiting for a double and since that entered data is not a double it doesn't consume that input so that next time it still has the same data pending in the input and still is not a double and so on. That's why if you read it as string you don't have that problem as it gets consumed from the input and then you can parse it. I've updated the answer with this info. It would be great if you could mark the answer as correct if it has worked by clicking on the check mark. – jeprubio Apr 11 '20 at 14:49
  • Another solution tor the infinite loop would be to execute `scanner.nextLine()` inside the catch block so that that input gets consumed and then continue using `scnr.nextDouble` – jeprubio Apr 11 '20 at 15:08
  • May I suggest using nextLine() rather than next() for the numerical input? – NomadMaker Apr 11 '20 at 15:49
  • @NomadMaker this other possibility was also mentioned in the previous comment but I've updated the answer with an example of this anyway. Thanks. – jeprubio Apr 11 '20 at 16:00