Ошибка при синтаксическом анализе верхнего регистра, но нет ошибки при синтаксическом анализе нижнего регистра java

поэтому мой код представляет собой программу, определяющую, является ли вода температурной, газообразной или твердой при определенных температурах, за которой следует единица измерения (по Фаренгейту или по Цельсию).

Код работает для единиц «F», «f», «c», но не для прописных букв «C».

    public static void stateOfWater() {
    Scanner inputTempString = new Scanner(System.in);
    System.out.print("Enter temperature: ");
    String temperatureString = inputTempString.nextLine().trim();
    String unit = temperatureString.substring(temperatureString.length()-1);
    unit = unit.toLowerCase();
    temperatureString = temperatureString.replace(unit,"");
    double temperature =  Double.parseDouble(temperatureString);

        if ( (temperature <= 0 && unit.equals("c")) || (temperature <= 32 && unit.equals("f")) ) {
            System.out.println("The state of the water is: solid (ice). ");
        }

        if (  ( (0.0 <= temperature && temperature < 100) && unit.equals("c")  ) || (((32 <= temperature && temperature < 212) && unit.equals("f")))) {
            System.out.println("The state of the water is: liquid. ");
        }

        if ((temperature > 100 && unit.equals("c")) || (temperature > 212 && unit.equals("f")))  {
            System.out.println("The state of the water is: gaseous. ");
        }
    }

Я получаю эту ошибку, когда пытаюсь ввести температуру, которая содержит C в верхнем регистре:

Exception in thread "main" java.lang.NumberFormatException: For input string: "43C"
at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054)
at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.base/java.lang.Double.parseDouble(Double.java:543)
at lab2.Lab.stateOfWater(Lab.java:13)
at lab2.main.main(main.java:5)

Какова ваша входная строка?

oleg.cherednik 25.02.2019 14:22

Ваш анализ проблемы неверен. Вы заменяете «c» на «», чтобы получить температуру. Таким образом, «43C» даст «43C», и это не удастся преобразовать в число.

Nikhil Sahu 25.02.2019 14:23

Проблемный код: unit = unit.toLowerCase(); temperatureString = temperatureString.replace(unit,""); Для ввода 43Cunit становится c, но затем вы пытаетесь заменить c, которого даже нет в temperatureString. Я предлагаю сначала перевести весь temperatureString в нижний регистр, а затем отрезать единичный символ.

Alex Savitsky 25.02.2019 14:28

Я сомневаюсь, что это работает с прописными буквами F прямо сейчас, так как у него та же проблема, когда вы пытаетесь удалить строчные unit из все еще прописных temperatureString ..

Kevin Cruijssen 25.02.2019 14:36
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
4
302
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Почему я получаю это исключение?

Вы конвертируете единицу измерения в нижний регистр, а затем заменяете строчную строку пустой. Если ваша строка была 43C, она попытается заменить c пустой строкой... Ну, это, конечно, не работает.

Вы должны сначала отрезать единицу измерения от строки температуры а потом преобразовать единицу измерения в нижний регистр.

String input = inputTempString.nextLine().trim();
String unit = input.substring(input.length() - 1).toLowercase();
double temperature = Double.parseDouble(input.substring(0, input.length() - 1));

Но почему 43F работает, а 43C нет?

Причина, по которой это действительно работало для верхнего регистра F, заключается в том, что буква F является частью литерала с плавающей запятой, как указано в документации Double.parseDouble (строка), который, в свою очередь, ссылается на Double.valueOf (строка), который, в свою очередь, ссылается на Спецификация языка Java § 3.10.2, который ссылается на этот токен. как токен FloatTypeSuffix.


Кроме того, я предлагаю другой подход.

Я бы проанализировал ввод и преобразовал его в стандартизированную единицу, например, в Цельсий, а затем для части кода, отвечающей за печать состояния воды, мне нужно было написать только if операторы с одним или двумя сравнениями. Например, вместо вашего утверждения if, например:

(((0.0 <= temperature && temperature < 100) && unit.equals("c")  ) || (((32 <= temperature && temperature < 212) && unit.equals("f"))))

Я бы что-нибудь покороче:

String state = "";
if (temperature < 0) {
    state = "solid (ice)";
}
else if (temperature < 100) {
    state = "liquid";
}
else {
    state = "gaseous";
}

Спасибо! мтс мтс мтс

98wau 25.02.2019 14:50

На самом деле, вам даже не нужен блок! Просто проверьте последний символ данной строки и, если это «F» или «f», вычтите 32, чтобы получить градусы в градусах Цельсия.

public static void stateOfWater() {
    try (Scanner scan = new Scanner(System.in)) {
        System.out.print("Enter temperature (e.g. 35F or 35C): ");
        String str = scan.nextLine().trim();
        double degree = Double.parseDouble(str.substring(0, str.length() - 1));
        degree = Character.toUpperCase(str.charAt(str.length() - 1)) == 'F' ? degree : ((degree - 32) * 5) / 9;
        String state = Double.compare(degree, 0) <= 0 ? "solid (ice)" : Double.compare(degree, 100) < 0 ? "liquid" : "gaseous";
        System.out.println("The state of the water is: " + state + '.');
    }
}

Это дает неверные результаты. Отличается не только перехватывать между этими шкалами, но и склон.

MC Emperor 25.02.2019 14:48

@MCEmperor Спасибо, забыл об этом. Фиксированный.

oleg.cherednik 25.02.2019 14:51

Другие вопросы по теме