import java.util.Scanner; import java.io.File; import java.io.FileNotFoundException; /** * 温度转换器示例程序(Java) * 支持摄氏度(C)与华氏度(F)之间互转 * 增强版本:支持命令行参数和文件批量转换 */ public class TemperatureConverter { /** * 将摄氏度转换为华氏度。 * * 换算公式:F = C × 9/5 + 32 * * @param c 摄氏温度(浮点数) * @return 对应的华氏温度(浮点数) */ public static double celsiusToFahrenheit(double c) { return c * 9.0 / 5.0 + 32.0; } /** * 将华氏度转换为摄氏度。 * * 换算公式:C = (F - 32) × 5/9 * * @param f 华氏温度(浮点数) * @return 对应的摄氏温度(浮点数) */ public static double fahrenheitToCelsius(double f) { return (f - 32.0) * 5.0 / 9.0; } /** * 从粘连格式中提取数值和单位。 * 例如:100f → ["100", "F"],36.6c → ["36.6", "C"],100 f → ["100", "F"] * 支持单位前的空格。 * * @param input 粘连格式的输入 * @return 包含数值和单位的数组,如果无法提取则返回 null */ public static String[] extractAdjacent(String input) { String trimmed = input.trim(); // 使用正则表达式匹配粘连格式,允许单位前有空格 // 格式:数字(可选小数) + 可选空格 + C或F java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("^(\\d+(?:\\.\\d+)?)\\s*([CcFf])$"); java.util.regex.Matcher matcher = pattern.matcher(trimmed); if (matcher.matches()) { String value = matcher.group(1); String unit = matcher.group(2).toUpperCase(); return new String[]{value, unit}; } return null; } /** * 分析并提供错误诊断和建议。 * 在交互模式中使用此方法进行智能纠正。 * * @param input 用户输入 * @param isInteractiveMode 是否为交互模式 * @return 如果输入有效返回true,否则返回false并打印诊断信息 */ public static boolean analyzeAndSuggestFix(String input, boolean isInteractiveMode) { input = input.trim(); // 1. 检查粘连单位模式(如 100f) String[] adjacent = extractAdjacent(input); if (adjacent != null) { // 判断是否真正是粘连格式(数值和单位直接相连,无空格) boolean isDirectlyAdjacent = input.matches("^\\d+(?:\\.\\d+)?[CcFf]$"); if (isDirectlyAdjacent && isInteractiveMode) { System.out.println("✓ 已自动纠正输入:'" + input + "' → '" + adjacent[0] + " " + adjacent[1] + "'"); } // 进行转换 return convertWithValidatedInput(Double.parseDouble(adjacent[0]), adjacent[1]); } // 2. 分割输入 String[] parts = input.split("\\s+"); // 3. 检查缺少单位模式(如 100) if (parts.length == 1) { try { Double.parseDouble(parts[0]); // 能解析为数字,但缺少单位 if (isInteractiveMode) { System.out.println("⚠️ 缺少温度单位!"); System.out.println(" 请指定 C(摄氏度)或 F(华氏度)"); System.out.println(" 示例:" + parts[0] + " C 或 " + parts[0] + " F"); } return false; } catch (NumberFormatException e) { // 既不是数字也不是正确格式 if (isInteractiveMode) { System.out.println("❌ 温度值不是有效的数字:'" + parts[0] + "'"); System.out.println(" 请输入数值(如 36.6, 100 等)"); System.out.println(" 示例:36.6 C"); } return false; } } // 4. 验证数值有效性 try { double value = Double.parseDouble(parts[0]); String unit = parts[1].toUpperCase(); // 5. 验证单位有效性 if (!unit.startsWith("C") && !unit.startsWith("F")) { if (isInteractiveMode) { System.out.println("❌ 不支持的温度单位:'" + unit + "'"); System.out.println(" 支持的单位:C(摄氏度)或 F(华氏度)"); System.out.println(" 示例:" + parts[0] + " C 或 " + parts[0] + " F"); } return false; } // 转换成功 return convertWithValidatedInput(value, unit); } catch (NumberFormatException e) { if (isInteractiveMode) { System.out.println("❌ 温度值不是有效的数字:'" + parts[0] + "'"); System.out.println(" 请输入数值(如 36.6, 100 等)"); System.out.println(" 示例:36.6 C"); } return false; } } /** * 使用验证过的数值和单位进行转换。 * 这是真正的转换逻辑,不包含错误处理。 * * @param value 温度值 * @param unit 单位(C 或 F) * @return 始终返回 true(如果调用说明数据有效) */ public static boolean convertWithValidatedInput(double value, String unit) { if (unit.startsWith("C")) { double f = celsiusToFahrenheit(value); System.out.printf("%.2f °C = %.2f °F%n", value, f); } else if (unit.startsWith("F")) { double c = fahrenheitToCelsius(value); System.out.printf("%.2f °F = %.2f °C%n", value, c); } return true; } /** * 处理单个温度转换(命令行/文件模式用,宽松验证)。 * * @param input 温度输入字符串,格式:"数值 单位",例如 "36.6 C" * @return 转换成功返回true,失败返回false */ public static boolean convertSingleTemperature(String input) { input = input.trim(); // 检查输入是否为空 if (input.isEmpty()) { return false; } // 检查粘连单位并自动分离 String[] adjacent = extractAdjacent(input); if (adjacent != null) { try { return convertWithValidatedInput(Double.parseDouble(adjacent[0]), adjacent[1]); } catch (NumberFormatException e) { return false; } } // 按空白字符分割输入字符串 String[] parts = input.split("\\s+"); try { double value = Double.parseDouble(parts[0]); // 如果没有单位,在命令行/文件模式中仍然尝试转换(宽松模式) // 但在交互模式中会被 analyzeAndSuggestFix 拒绝 String unit = (parts.length > 1) ? parts[1].toUpperCase() : "C"; if (unit.startsWith("C")) { double f = celsiusToFahrenheit(value); System.out.printf("%.2f °C = %.2f °F%n", value, f); } else if (unit.startsWith("F")) { double c = fahrenheitToCelsius(value); System.out.printf("%.2f °F = %.2f °C%n", value, c); } else { return false; } return true; } catch (NumberFormatException e) { return false; } catch (Exception e) { return false; } } /** * 从文件中批量读取温度数据并进行转换。 * 文件中每一行包含一个温度及其单位。 * * @param filename 文件路径 */ public static void convertFromFile(String filename) { File file = new File(filename); if (!file.exists()) { System.out.println("文件不存在:" + filename); return; } try { Scanner fileScanner = new Scanner(file); int lineNum = 0; int successCount = 0; System.out.println("从文件读取温度数据:" + filename); System.out.println("========================================"); while (fileScanner.hasNextLine()) { lineNum++; String line = fileScanner.nextLine(); // 跳过空行和注释行(以#开头) if (line.trim().isEmpty() || line.trim().startsWith("#")) { continue; } System.out.print("第 " + lineNum + " 行:"); if (convertSingleTemperature(line)) { successCount++; } } System.out.println("========================================"); System.out.println("处理完成:共处理 " + lineNum + " 行,成功转换 " + successCount + " 条。"); fileScanner.close(); } catch (FileNotFoundException e) { System.out.println("无法打开文件:" + filename); } } /** * 交互式模式:提示用户输入温度进行转换,使用智能诊断。 */ public static void interactiveMode() { Scanner scanner = new Scanner(System.in); System.out.println("========================================"); System.out.println("温度转换器 - 交互式模式"); System.out.println("========================================"); System.out.println("请输入要转换的温度与单位(例如 36.6 C 或 97 F)"); System.out.println("输入 'quit' 或 'exit' 退出程序"); System.out.println("========================================"); while (true) { System.out.print("> "); String input = scanner.nextLine(); if (input.equalsIgnoreCase("quit") || input.equalsIgnoreCase("exit")) { System.out.println("程序退出。"); break; } // 在交互模式中使用智能诊断 if (!analyzeAndSuggestFix(input, true)) { // 诊断方法已经打印了具体的错误信息 } } scanner.close(); } /** * 显示使用说明。 */ public static void showUsage() { System.out.println("温度转换器 - 使用说明"); System.out.println("========================================"); System.out.println("用法1(命令行参数模式):"); System.out.println(" java TemperatureConverter_PytoJava <温度> <单位>"); System.out.println(" 例如:java TemperatureConverter_PytoJava 36.6 C"); System.out.println(); System.out.println("用法2(批量转换模式):"); System.out.println(" java TemperatureConverter_PytoJava <文件路径>"); System.out.println(" 例如:java TemperatureConverter_PytoJava temperatures.txt"); System.out.println(" 文件格式:每行一条温度数据,格式为 '温度 单位'"); System.out.println(); System.out.println("用法3(交互式模式):"); System.out.println(" java TemperatureConverter_PytoJava"); System.out.println(" 然后按提示输入温度数据"); System.out.println("========================================"); } /** * 程序入口主方法。 * 支持三种模式: * 1. 命令行参数模式:java TemperatureConverter_PytoJava 36.6 C * 2. 文件批量转换:java TemperatureConverter_PytoJava temperatures.txt * 3. 交互式模式:java TemperatureConverter_PytoJava * * @param args 命令行参数 */ public static void main(String[] args) { if (args.length == 0) { // 交互式模式 interactiveMode(); } else if (args.length == 1) { // 检查是否为文件路径(包含.txt或其他扩展名,或者是一个存在的文件) File file = new File(args[0]); if (file.exists() && file.isFile()) { // 文件批量转换模式 convertFromFile(args[0]); } else if (args[0].equalsIgnoreCase("-h") || args[0].equalsIgnoreCase("--help")) { // 显示帮助信息 showUsage(); } else { // 可能是单个温度但缺少单位,默认使用摄氏度 System.out.println("处理输入:" + args[0]); convertSingleTemperature(args[0]); } } else if (args.length == 2) { // 命令行参数模式:温度和单位 convertSingleTemperature(args[0] + " " + args[1]); } else { showUsage(); } } }