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
Scannerin every method, and callingscan.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-whilewithout a proper exit condition leads to endless loops. - Using
Floatinstead ofdouble: You wanted double-type validation, so we'll switch todoublefor 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 Scannerthat's used everywhere in the program. Multiple Scanner instances onSystem.incan 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. WhenDouble.parseDouble()fails, we've already read the entire input line withscanner.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-whileloop. The loop continues only if the user enters "y" when asked to continue. TheaskToContinue()method handles validating the user's restart choice, so no more infinite loops.
4. Double-Type Input Validation
- Switched all numeric variables from
FloattoDoubleto meet your requirement of double-type input. UsedDouble.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
printffor 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
相关产品推荐
相关产品推荐

