You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

338 lines
13 KiB

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
/**
* 温度转换器示例程序(Java)
* 支持摄氏度(C)与华氏度(F)之间互转
* 增强版本:支持命令行参数和文件批量转换
*/
public class TemperatureConverter_PytoJava {
/**
* 将摄氏度转换为华氏度。
*
* 换算公式: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();
}
}
}