Try-catch создает бесконечный цикл

Мне нужно иметь возможность принимать пользовательский ввод до тех пор, пока ввод не превысит начальную цену, но мне также нужно сделать его устойчивым, чтобы пользователь не мог сломать программу, введя что-то отличное от двойного / целого числа. Если пользователь вводит что-то отличное от double/int.

Проблема в том, что он создает цикл и повторяет "Пожалуйста, введите действительную валюту" + "Пожалуйста, введите: цена"

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

2 ответа

Решение

Причина, по которой вы видите бесконечный цикл, заключается в том, что вы никогда не удаляете неправильную запись из ввода. Если вы посмотрите на документы, он говорит

Если перевод успешен, сканер продвигается мимо соответствующего ввода.

Когда это не удается, вы должны позвонить kb.next() удалить ввод, который не соответствует двойному, чтобы можно было перейти к следующей записи пользователя. В противном случае вы будете пытаться анализировать один и тот же недействительный текст снова и снова:

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

Несколько других вещей, которые вы можете улучшить. Там нет необходимости использовать try а также catch здесь, так как вы можете использовать hasNextDouble способ проверить правильность ввода. Если вы решите придерживаться обработки исключений, вы должны поймать InputMismatchException а не общий Exceptionили вы рискуете столкнуться с некоторыми другими проблемами (например, если ввод исчерпан). Вы также можете положить continue в случае сбоя ввода, так что он не оценивает остальную часть кода, который предполагает, что вы правильно прочитали значение.

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

Обратите внимание, что в вашей логике все еще есть проблема, и цикл никогда не завершится (так как payment всегда сбрасывается на ноль). Я полагаю, вы хотите сделать totalPayment < price вместо.

Поскольку вы хотите, чтобы он распознавал любой ввод, но использовал только двойные значения, попробуйте Double.parseDouble(String), Я также переместил оставшуюся логику в ваш блок try, поскольку это должно происходить только при получении правильного ввода. Если он не может разобрать дубль, он вырывается без попытки использования остальной логики и пытается снова.

while (payment < price && price > 0){
    try{
        payment = Double.parseDouble(kb.next());
        if (payment > 0){
            totalPayment += payment;
            price -= payment;
            price = (price * 100); 
            payment = 0;
        }
        if (totalPayment < initialPrice){
            System.out.println("Please Insert:" + price);
        }
    }
    catch (Exception e) {
        System.out.println("Please enter valid currency");
    }
}
Другие вопросы по тегам