You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java双精度(double)输入验证及程序循环问题求助

Java Input Validation & Program Flow Fixes

Hey there! Let's work through your two main issues: proper double-type input validation, and fixing those annoying quirks in your ingredient calorie calculator. I'll walk you through the problems in your current code and show you a polished, working version with explanations.

Key Issues in Your Current Code

First, let's break down why you're seeing those problems:

  • Extra keypress after invalid input: You're creating a new Scanner in every method, and calling scan.nextLine() unnecessarily in catch blocks. This causes the scanner to wait for an extra input line before proceeding.
  • Infinite loop when trying to restart: Your original code doesn't wrap the full calculation flow in a loop—adding a do-while without a proper exit condition leads to endless loops.
  • Using Float instead of double: You wanted double-type validation, so we'll switch to double for more precision.

Fixed & Improved Code

Here's the revised version that addresses all your requirements:

import java.util.Scanner;

public class IngredientCalorieCalculator {
    // Use a single Scanner instance across the program to avoid input stream issues
    private static final Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        boolean shouldContinue;
        do {
            String nameOfIngredient = null;
            Double numberOfCups = null;
            Double numberOfCaloriesPerCup = null;
            Double totalCalories;

            // Get valid ingredient name
            while (nameOfIngredient == null) {
                nameOfIngredient = setIngredients();
            }

            // Get valid cup count (double type)
            while (numberOfCups == null) {
                numberOfCups = setNumberOfCups();
            }

            // Get valid calories per cup (double type)
            while (numberOfCaloriesPerCup == null) {
                numberOfCaloriesPerCup = setNumberOfCaloriesPerCup();
            }

            // Calculate and display result
            totalCalories = numberOfCups * numberOfCaloriesPerCup;
            System.out.printf("%s uses %.2f cups and this amount contains %.2f total calories.%n%n",
                    nameOfIngredient, numberOfCups, totalCalories);

            // Ask user if they want to restart
            shouldContinue = askToContinue();
        } while (shouldContinue);

        // Close the scanner when done
        scanner.close();
        System.out.println("Thanks for using the calculator!");
    }

    public static String setIngredients() {
        System.out.println("Please enter the name of the ingredient: ");
        try {
            String ingredient = scanner.nextLine().trim();
            if (ingredient.isEmpty()) {
                System.out.println("Ingredient name can't be empty. Try again.");
                return null;
            }
            return ingredient;
        } catch (Exception e) {
            System.out.println("Error reading input. Try again.");
            return null;
        }
    }

    public static Double setNumberOfCups() {
        System.out.println("Please enter number of cups: ");
        try {
            String input = scanner.nextLine().trim();
            Double cups = Double.parseDouble(input);
            if (cups <= 0) {
                System.out.println("Cups must be a positive number. Try again.");
                return null;
            }
            return cups;
        } catch (NumberFormatException e) {
            System.out.println("Invalid input! Please enter a numeric value (e.g., 1.5). Try again.");
            return null;
        } catch (Exception e) {
            System.out.println("Error reading input. Try again.");
            return null;
        }
    }

    public static Double setNumberOfCaloriesPerCup() {
        System.out.println("Please enter number of calories per cup: ");
        try {
            String input = scanner.nextLine().trim();
            Double calories = Double.parseDouble(input);
            if (calories < 0) {
                System.out.println("Calories can't be negative. Try again.");
                return null;
            }
            return calories;
        } catch (NumberFormatException e) {
            System.out.println("Invalid input! Please enter a numeric value (e.g., 120.75). Try again.");
            return null;
        } catch (Exception e) {
            System.out.println("Error reading input. Try again.");
            return null;
        }
    }

    private static boolean askToContinue() {
        System.out.println("Would you like to calculate another ingredient? (y/n): ");
        String response = scanner.nextLine().trim().toLowerCase();
        while (!response.equals("y") && !response.equals("n")) {
            System.out.println("Please enter 'y' for yes or 'n' for no: ");
            response = scanner.nextLine().trim().toLowerCase();
        }
        return response.equals("y");
    }
}

What Changed & Why?

Let's go through the improvements one by one:

1. Single Scanner Instance

  • I created a single static Scanner that's used everywhere in the program. Multiple Scanner instances on System.in can cause unexpected behavior (like leftover newline characters being read as empty input), which was contributing to your extra keypress issue.

2. Fixed Extra Keypress Problem

  • Removed the unnecessary scan.nextLine() calls in catch blocks. When Double.parseDouble() fails, we've already read the entire input line with scanner.nextLine()—calling it again would force the user to enter another line, hence the extra keypress.

3. Working Restart Loop

  • Wrapped the entire calculation logic in a do-while loop. The loop continues only if the user enters "y" when asked to continue. The askToContinue() method handles validating the user's restart choice, so no more infinite loops.

4. Double-Type Input Validation

  • Switched all numeric variables from Float to Double to meet your requirement of double-type input. Used Double.parseDouble() to parse input, and added checks for positive/non-negative values to make validation stricter.

5. Better User Feedback

  • Added checks for empty ingredient names and invalid numeric values (like negative calories) to guide the user more clearly. Used printf for cleaner output formatting with decimal places.

Bonus Tips for Input Validation

  • Always trim user input (using trim()) to ignore accidental leading/trailing spaces.
  • Add range checks (like ensuring cups are positive) to make your validation more robust than just checking for numeric types.
  • Close the scanner when your program finishes to free up resources (though for console apps, it's less critical, but good practice).

内容的提问来源于stack exchange,提问作者ThatGuy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 09:39:07