我在传递 char 而不是 int 后得到奇怪的循环行为

I'm getting weird loop behaviour after passing char instead int

提问人:Batiievskyi 提问时间:6/2/2021 更新时间:6/2/2021 访问量:40

问:

我正在解决一个问题 - <华氏度/摄氏转换器>:JavaRush Course

  1. 询问用户转化方向
  2. 询问用户温度
  3. 转换并打印出结果温度

我正在尝试在一个单独的方法上打破程序,以了解如何使用方法以及如何传递变量(我是编程初学者)

这是我的代码:

import java.util.Scanner;

public class FahrenheitCelsius {
    private static final Scanner sc = new Scanner(System.in);

    public static void main(String[] args) {
        System.out.println("---< Fahrenheit / Celsius Converter >---");
        String direction = getDirection();
        int temperature = getTemperature(direction);
        getResult(direction, temperature);
        sc.close();
    }

    // let's get direction of conversion from user input
    static String getDirection() {
        String direction;
        do {
            System.out.print("Convert from F or C: ");
            direction = sc.nextLine();
        } while (!direction.equals("F") && !direction.equals("C"));
        return direction;
    }

    // let's get temperature from user
    static int getTemperature(String direction) {
        int temperature;
        System.out.print("temperature in " + direction + ": ");
        while (!sc.hasNextInt()) {
            System.out.print("temperature in " + direction + ": ");
            sc.nextLine();
        }
        temperature = sc.nextInt();
        return temperature;
    }

    // let's convert Fahrenheit to Celsius
    static int fahrenheitToCelsius(int temperatureF) {
        return (temperatureF - 32) * 5 / 9;
    }

    // let's convert Celsius to Fahrenheit
    static int celsiusToFahrenheit(int temperatureC) {
        return temperatureC * 9 / 5 + 32;
    }

    // let's get result using direction and temperature we got
    static void getResult(String direction, int temperature) {
        int result;
        if (direction.equals("F")) {
            result = fahrenheitToCelsius(temperature);
            System.out.println("result temperature: " + result + "C");
        } else {
            result = celsiusToFahrenheit(temperature);
            System.out.println("result temperature: " + result + "F");
        }
    }
}

但!!!

我正在尝试使用循环编写方法。 喜欢这个:getTemperaturedo while

    static int getTemperature(String direction) {
        int temperature;
        do {
            System.out.print("temperature in " + direction + ": ");
            sc.nextInt();
        } while (!sc.hasNextInt());
        temperature = sc.nextInt();
        return temperature;
    }

起初,我在每个方法中使用了单独的 Scanner 实例。我得到了 - 如果用户取消输入noSuchElementExeptioncharacters

然后我有了这个想法,我不必在方法中关闭扫描仪。getDirection

然后我在 Stackoverflow 中修改了一些建议,并创建了单独的 Scanner 实例并将其传递给方法static final

现在我得到 - 如果用户输入代替infinite loopcharactersintegers

我知道这是 Scanner 和这个东西的一些奇怪行为。nextLine()

但是不知道如何在没有这个错误的情况下使用循环。getTemperaturedo while

提前感谢伙计们。

java.util.scanner 执行

评论


答:

1赞 DevilsHnd - 退した 6/2/2021 #1

您的方法可能包含:main()

System.out.println("---< Fahrenheit / Celsius Converter >---");
String direction = "";
// Use of the String#matches() method with a small Regular Expression.
// (?i)     Ignore Letter Case
// [FC]     Only allow the character q, or Q
while (!direction.matches("(?i)[q]")) {
    direction = getDirection();
    if (!direction.matches("(?i)[q]")) {
        int temperature = getTemperature(direction);
        printResult(direction, temperature);
    }
    System.out.println();
}

该方法可能如下所示:getDirection()

// let's get direction of conversion from user input
public static String getDirection() {
    String direction = "";
    while (direction.isEmpty()) {
        System.out.println("Enter temperature scale to convert:");
        System.out.println("  F) Fahrenheit");
        System.out.println("  C) Celsius");
        System.out.println("  Q) Quit");
        System.out.print("Your choice: --> ");
        direction = sc.nextLine();
        if (direction.equalsIgnoreCase("q")) {
            System.out.println("\nBye-Bye\n");
            break;
        }
        // Use of the String#matches() method with a small Regular Expression.
        // (?i)     Ignore Letter Case
        // [FC]     Only allow the characters F, f, C, or c (q is handled ahead of time)
        if (!direction.matches("(?i)[FC]")) {
            System.err.println("Invalid Temperature Scale Type (" + direction 
                             + ")! Must be F or C! Try again...\n");
            direction = "";
        }
    } 
    return direction;
}

该方法可能如下所示:getTemperature()

// let's get temperature from user
private static int getTemperature(String direction) {
    String temp = "";
    // 'Ternary Operators' used here
    String directString = (direction.equalsIgnoreCase("f") ? "Fahrenheit" : "Celsius");
    String otherDirectString = (direction.equalsIgnoreCase("f") ? "Celsius" : "Fahrenheit");
    System.out.println();
    System.out.println("Convert a Temperature in " + directString + " to " + otherDirectString + ":");
    do {
        System.out.print("Enter a temperature in " + directString + ": --> ");
        temp = sc.nextLine().trim();
        // Since you're working with integer for temperature...
        // Use of the String#matches() method with a small Regular Expression.
        // ("\\d+")   Must be a string representation of an Integer numerical 
        // value with 1 (or possibly) more digits.
        if (!temp.matches("\\d+")) {
            System.err.println("Invalid Temperature Supplied (" + temp + ")! Try Again..." );
            temp = "";
        }
    } while (temp.isEmpty());
    return Integer.valueOf(temp);
}

之所以改名,是因为这就是它本质上所做的一切。它并没有真正得到任何东西:getResult()printResult()

// let's get result using direction and temperature we got
static void printResult(String direction, int temperature) {
    // 'Ternary Operator' used here
    System.out.println("Converted temperature is : " 
            + (direction.toUpperCase().equals("F") 
                 ? fahrenheitToCelsius(temperature) + "C" 
                     : celsiusToFahrenheit(temperature) + "F"));
}

其他杂项方法保持不变:

// let's convert Fahrenheit to Celsius
public static int fahrenheitToCelsius(int temperatureF) {
    return (temperatureF - 32) * 5 / 9;
}

// let's convert Celsius to Fahrenheit
public static int celsiusToFahrenheit(int temperatureC) {
    return temperatureC * 9 / 5 + 32;
}

阅读代码中的注释。您当然会注意到,使用 String#matches() 方法进行验证,以及注释中解释的各种小正则表达式

您还会注意到使用三元运算符来减少 IF/ELSE 语句的显示。

评论

0赞 Batiievskyi 6/3/2021
我没想到会有这么详细的答案。对我来说,这已经是程序结构设计的下一个层次。我一定会把你给我的所有这些技巧付诸实践。非常感谢 DevilsHnd 提供此信息和相关主题的链接。