Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Try-catch creates infinite loop [duplicate]

I need to be able to take user input until the input is greater than the initial price, but I also need to make it robust so that the user can't break the program by entering something other than a double/integer. If the user does enter something other than a double/int.

The problem is that it creates a loop and repeats "Please enter valid currency" + "Please enter: price"

 public static double findChange()
{
    System.out.println("\nPlease insert: " + price + " (enter payment amount)");
    initialPrice = price;
    while (payment < price)
    {  
        try{
            payment = kb.nextDouble();
        }
        catch (Exception e)
        {
            System.out.println("Please enter valid currency");
        }
        if (payment > 0){
            totalPayment += payment;
            price -= payment;
            price = (price * 100);
            payment = 0;
        }
        if (totalPayment < initialPrice)
            System.out.println("Please Insert:" + price);
    }

    change = totalPayment - initialPrice;
    change = Math.round(change * 100);
    change = change / 100;
    System.out.println("\nChange Given: $" + change);

    return change;
}
like image 398
A Allen Avatar asked Feb 09 '23 07:02

A Allen


1 Answers

The reason you're seeing an infinite loop is that you never clear the invalid entry out of the input. If you look at the docs, it says

If the translation is successful, the scanner advances past the input that matched.

When it fails, you should call kb.next() to remove the input that did not match a double, so that you can move on to the next user entry. Otherwise, you'll keep trying to parse the same invalid text over and over:

catch (Exception e)
{
    System.out.println("Please enter valid currency");
    kb.next();
}

A few other things you can improve as well. There's no need to be using a try and catch here, since you can use the hasNextDouble method to check that the input is valid. If you do decide to stick with exception handling though, you should catch InputMismatchException rather than a generic Exception, or else you risk running into some more problems (for example, if the input gets exhausted). You can also put a continue in when the input fails, so that it doesn't evaluate the rest of the code which is assuming that you correctly read a value.

if(kb.hasNextDouble()){
    payment = kb.nextDouble();
} else{
    System.out.println("Please enter valid currency");
    kb.next();
    continue;
}

Note that there's still a problem with your logic, and the loop will never exit (since payment always gets reset to zero). I assume you want to do totalPayment < price instead.

like image 88
resueman Avatar answered Feb 13 '23 22:02

resueman