0

I am just beginning to learn Java I am working on a quiz and I want to use Exception handling for some errors that might happen. 1. The user should only answer A,B,C if they answer D or any other letters there must be an exception then they can try again 2. The user should not have blank answers, if they leave a blank on a question there must be an exception then they can try again

And is it recommended to use switch case for this? (this is what I've done)

try {
    String answer1 = scan.next();

    switch(answer1.toUpperCase()) {
        case "A": 
            System.out.println("Wrong, correct answer is B");
            break;
        case "B": 
            score++;
            System.out.println("Correct!"); 
            break;
        case "C":
            System.out.println("Wrong, correct answer is B");
            break;
        default:
            throw new InputMismatchException(); 
    }       
} catch (InputMismatchException ex) {
    System.out.println("INVALID! Must be letters only, Try again");
}

how will I do the other exceptions ? When I try to run it when the user input d it will also print Invalid must be letters only .. Thank you :)

deHaar
  • 17,687
  • 10
  • 38
  • 51
yoonsanha
  • 49
  • 1
  • 1
  • 10
  • "The user should not have blank answers" ... with your current code, they can't have blank answers. – Tom Jan 21 '19 at 15:35
  • should I change switch case? to if else so that I can have exception handling for blank answers? what should I do? thank you very much – yoonsanha Jan 21 '19 at 15:38
  • Possible duplicate of [Java: checked vs unchecked exception explanation](https://stackoverflow.com/questions/6115896/java-checked-vs-unchecked-exception-explanation) – Andronicus Jan 21 '19 at 15:39

3 Answers3

3

The switch statement is fine, but you are misusing exceptions. Exceptions are for exceptional situations. A user entering invalid input is not exceptional behaviour. It's very much expected behaviour; users are stupid.

If you just want to print the error, you can move the println to the default case.

If you want to give the user a second chance, the common solution is a do-while loop:

boolean isValidInput = true;
do
{
    String answer1 = scan.next();
    switch(answer1.toUpperCase()) {
        case "A": 
            System.out.println("Wrong, correct answer is B");
            isValidInput = true;
            break;
        case "B": 
            score++;
            System.out.println("Correct!"); 
            isValidInput = true;
            break;
        case "C":
            System.out.println("Wrong, correct answer is B");
            isValidInput = true;
            break;
        default:
            System.out.println("INVALID! Must be letters only, Try again");
            isValidInput = false;
    }
} 
while (!isValidInput);

It's also worth noting that, given that the behaviour for A and C is identical, you can combine the cases:

case "B":
    score++;
    System.out.println("Correct!");
    isValidInput = true;
    break;
case "A":
case "C":
    System.out.println("Wrong, correct answer is B");
    isValidInput = true;
    break;
Michael
  • 41,989
  • 11
  • 82
  • 128
  • +1 for the exception misuse, but I think I'd use a more usual `while(!isValidInput){...}` loop with the advantage of not definining `isValidInput` to `true` when it isn't. – Aaron Jan 21 '19 at 15:45
  • @Michael maybe it is a requirement for the OP to use custom Exceptions to handle such situations (eg school assignment) – nullPointer Jan 21 '19 at 15:45
  • 1
    @funkyjelly Well, he said "I **want to** use Exception handling" not "I **have to**". If it is a requirement then it's a bad one. – Michael Jan 21 '19 at 15:46
  • @Aaron You still need to define `isValidInput` to true before a while loop. – Michael Jan 21 '19 at 15:47
  • 1
    @Michael no, my point is that you'd define it to `false` (and `hasReceivedValidInput` would be a more appropriate name). You'd have to set it to `true` for the three valid cases though, which is a disadvantage of the solution. – Aaron Jan 21 '19 at 15:49
  • @Aaron Oh, sorry I get you now. Yeah, swings and roundabouts really. – Michael Jan 21 '19 at 15:51
  • 3
    This will get stuck in an infinite loop once the user enters something invalid. You never set it back to `true`. Also, you miss `String answer1 = scan.next();` in the loop. – TiiJ7 Jan 21 '19 at 15:52
  • @TiiJ7 Thanks, fixed :) I should have tested it really – Michael Jan 21 '19 at 16:10
0

Better method will be to use if else in this case. You can try this:

String answer = scan.next()
String answer1 = answer.toUpperCase();
if (answer1.charAt(0) == 'A'){
    System.out.println("Wrong, correct answer is B");
} else if (answer1.charAt(0) == 'B') {
    score++;
    System.out.println("Correct!");
} else if (answer1.charAt(0) == 'C') {
    System.out.println("Wrong, correct answer is B");
} else if (answer1.charAt(0) > 'C' && answer1.charAt(0) <= 'Z') {
    throw new WrongLetterException()
} else {
    throw new OtherException()
} 
//catch statement
catch (WrongLetterException ex) 
{
    System.out.println("Only A, B or C, Try again");
}
catch (OtherException ex) 
{
    System.out.println("INVALID! Must be letters only, Try again");
}
0

I would have gone for following code, if it should really do the same as before (although looks a bit weird to me, throwing an exception and then simply plotting an statement to console):

    private static void checkAnswer(String answer) {
    try {
        if (answer == null || answer.trim().length() == 0) {
            throw new VoidAnswerException();
        }
        switch(answer.toUpperCase()) {
            case "B":
                score++;
                System.out.println("Correct!");
                break;
            case "A":
            case "C":
                System.out.println("Wrong, correct answer is B");
                break;
            default:
                throw new IllegalAnswerException();
        }
    } catch (VoidAnswerException e) {
        System.out.println("INVALID! Must not be empty, Try again");
    } catch (IllegalAnswerException e) {
        System.out.println("INVALID! Must be letters only, Try again");
    }
}


static class VoidAnswerException extends Exception {}

static class IllegalAnswerException extends Exception {}

Remark: There is no different case handling for 'A' and 'C', therefore you can use same case block for both.

Personally I would rather go for "if" instead of the switch/case block, because I would anticipate code changes/improvements when evolving...