Java临时转换程序。输出正确,但有错误

Java临时转换程序。输出正确,但有错误,java,string,debugging,Java,String,Debugging,我不确定我做错了什么,任务是创建一个代码,将温度从C转换为F或从F转换为C,直到用户决定完成为止。如果出现无效字符,我还应该打印一条错误消息,让用户在不再次要求数字部分的情况下更正它 在输入除“c”、“c”、“f”或“f”以外的值之前,程序似乎运行正常。在这一点上,我仍然得到了所需的输出,但在这里我得到了一个错误,这是我的代码 import java.util.Scanner; public class ProjectThree { public static void main(S

我不确定我做错了什么,任务是创建一个代码,将温度从C转换为F或从F转换为C,直到用户决定完成为止。如果出现无效字符,我还应该打印一条错误消息,让用户在不再次要求数字部分的情况下更正它

在输入除“c”、“c”、“f”或“f”以外的值之前,程序似乎运行正常。在这一点上,我仍然得到了所需的输出,但在这里我得到了一个错误,这是我的代码

import java.util.Scanner;

public class ProjectThree 
{
    public static void main(String[] args)
    {
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Please enter a temperature to be converted followed"
            + "\nby a C or c for Celsius or an F or f for Fahrenheit. If "
            + "\nfinished converting temperatures enter done.");
        String userInput, intString;
        userInput = keyboard.nextLine();

        while (!(userInput.equalsIgnoreCase("done")))
        {
            int length, temp, degreesC, degreesF;
            length = userInput.length();
            intString = userInput.substring(0,length - 1);
            temp = Integer.parseInt(intString);
            char scale = userInput.charAt(length - 1);

            while (!((scale == 'c') || (scale == 'C') || (scale =='f') || 
                (scale == 'F')))
            {
                System.out.println("Error: Invalid temperature unit. Enter a C or c"
                    + " for Celsius or an F or f for Fahrenheit.");
                String errorInput = keyboard.next();
                scale = errorInput.charAt(0);
                userInput = intString + errorInput;
            }
            switch (scale)
            {
                case 'C':
                case 'c':
                    degreesF = (9 * (temp / 5) + 32);
                    System.out.println(userInput + " is equal to " + degreesF 
                        + "F");
                    break;
                case 'F':
                case 'f':
                    degreesC = (5 * (temp - 32)) / 9;
                    System.out.println(userInput + " is equal to " + degreesC 
                        + "C");
                    break;
            }
            System.out.println("\nPlease enter a temperature to be converted followed"
                + "\nby a C or c for Celsius or an F or f for Fahrenheit. If "
                + "\nfinished converting temperatures enter done.");
            userInput = keyboard.nextLine();
        }
    }
}
错误是

Please enter a temperture to be converted followed
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
by a C or c for Celsius or an F or f for Farenheit. If 
finished converting tempertures enter done.
    at java.lang.String.substring(String.java:1955)
    at ChapterFour.ProjectThree.main(ProjectThree.java:33)
Java Result: 1
BUILD SUCCESSFUL (total time: 5 seconds)

一般来说,在错误的输入上有很多“可能”出错的地方,因为您没有任何错误检查。以下是我注意到的一些事情

1) 正如我认为其他人提到的,在对输入进行操作之前,您没有检查输入的长度。如果有人在没有其他任何东西的情况下按enter键,则可能会出现异常。如果输入无效输入,则相同

2) switch语句缺少默认子句。您应该添加打印“出错,请重试”的内容,以便您知道它发生了

3) 我看到您最初使用keyboard.nextLine()和keyboard.next()时只要求输入字符。如果在字符后输入回车符,则换行符可能会被以下nextLine()拾取,这会导致如上1所述打印错误。在谷歌搜索next()的行为以确认这一点时,我遇到了以下问题(看起来其他人也有类似的问题):


一般来说,在输入错误时,有很多东西“可能”出错,因为您没有任何错误检查。以下是我注意到的一些事情

1) 正如我认为其他人提到的,在对输入进行操作之前,您没有检查输入的长度。如果有人在没有其他任何东西的情况下按enter键,则可能会出现异常。如果输入无效输入,则相同

2) switch语句缺少默认子句。您应该添加打印“出错,请重试”的内容,以便您知道它发生了

3) 我看到您最初使用keyboard.nextLine()和keyboard.next()时只要求输入字符。如果在字符后输入回车符,则换行符可能会被以下nextLine()拾取,这会导致如上1所述打印错误。在谷歌搜索next()的行为以确认这一点时,我遇到了以下问题(看起来其他人也有类似的问题):


对于空字符串或长度为
1的字符串,您没有处理任何内容。因此它
会引发
异常
。您需要用户
尝试catch
阻塞或执行类似操作。我只需忽略输入字符串的长度
1

Scanner keyboard = new Scanner(System.in);

        System.out.println("Please enter a temperature to be converted followed"
                + "\nby a C or c for Celsius or an F or f for Fahrenheit. If "
                + "\nfinished converting temperatures enter done.");

        String userInput, intString;
        userInput = keyboard.nextLine();

        while (!(userInput.equalsIgnoreCase("done"))) {
            int length, temp, degreesC, degreesF;
            length = userInput.length();
            System.out.println(length);
            if (length > 1) {
                intString = userInput.substring(0, length - 1);
                temp = Integer.parseInt(intString);
                // System.out.println("Temp = " + temp);
                char scale = userInput.charAt(length - 1);
                // System.out.println("scale" + scale);

                while (!((scale == 'c') || (scale == 'C') || (scale == 'f') || (scale == 'F'))) {
                    System.out.println("Error: Invalid temperature unit. Enter a C or c"
                            + " for Celsius or an F or f for Fahrenheit.");
                    String errorInput = keyboard.next();
                    scale = errorInput.charAt(0);
                    userInput = intString + errorInput;
                }
                switch (scale) {
                case 'C':
                case 'c':
                    degreesF = (9 * (temp / 5) + 32);
                    System.out.println(userInput + " is equal to " + degreesF + "F");
                    break;
                case 'F':
                case 'f':
                    degreesC = (5 * (temp - 32)) / 9;
                    System.out.println(userInput + " is equal to " + degreesC + "C");
                    break;
                }
            }

            System.out.println("\nPlease enter a temperature to be converted followed"
                    + "\nby a C or c for Celsius or an F or f for Fahrenheit. If "
                    + "\nfinished converting temperatures enter done.");
            userInput = keyboard.nextLine();
        }
请注意
字符串子字符串(int-beginIndex,int-endIndex)
:返回从给定的
索引(beginIndex)
到指定的
索引(endIndex)
子字符串。例如,“Chaitanya”。
子字符串(2,5)
将返回“
ait
”。如果
beginIndex
小于零或
beginIndex>endIndex
endIndex
大于
字符串的
长度,则抛出
IndexOutOfBoundsException

在你的例子中,如果你只是简单地将
c
c
长度-1变为
0
,这是你的
最后一个索引
。而且你的
第一个索引
也是
0
。这就是你得到
索引自动边界感知的原因


希望你得到它。

对于空字符串或长度为
1的字符串,你没有处理任何事情。因此它
抛出
异常
。你需要用户
尝试catch
阻塞或像我这样做。对于输入字符串,我只是忽略长度
0
1

Scanner keyboard = new Scanner(System.in);

        System.out.println("Please enter a temperature to be converted followed"
                + "\nby a C or c for Celsius or an F or f for Fahrenheit. If "
                + "\nfinished converting temperatures enter done.");

        String userInput, intString;
        userInput = keyboard.nextLine();

        while (!(userInput.equalsIgnoreCase("done"))) {
            int length, temp, degreesC, degreesF;
            length = userInput.length();
            System.out.println(length);
            if (length > 1) {
                intString = userInput.substring(0, length - 1);
                temp = Integer.parseInt(intString);
                // System.out.println("Temp = " + temp);
                char scale = userInput.charAt(length - 1);
                // System.out.println("scale" + scale);

                while (!((scale == 'c') || (scale == 'C') || (scale == 'f') || (scale == 'F'))) {
                    System.out.println("Error: Invalid temperature unit. Enter a C or c"
                            + " for Celsius or an F or f for Fahrenheit.");
                    String errorInput = keyboard.next();
                    scale = errorInput.charAt(0);
                    userInput = intString + errorInput;
                }
                switch (scale) {
                case 'C':
                case 'c':
                    degreesF = (9 * (temp / 5) + 32);
                    System.out.println(userInput + " is equal to " + degreesF + "F");
                    break;
                case 'F':
                case 'f':
                    degreesC = (5 * (temp - 32)) / 9;
                    System.out.println(userInput + " is equal to " + degreesC + "C");
                    break;
                }
            }

            System.out.println("\nPlease enter a temperature to be converted followed"
                    + "\nby a C or c for Celsius or an F or f for Fahrenheit. If "
                    + "\nfinished converting temperatures enter done.");
            userInput = keyboard.nextLine();
        }
请注意
字符串子字符串(int-beginIndex,int-endIndex)
:返回从给定的
索引(beginIndex)
到指定的
索引(endIndex)
子字符串。例如,“Chaitanya”。
子字符串(2,5)
将返回“
ait
”。如果
beginIndex
小于零或
beginIndex>endIndex
endIndex
大于
字符串的
长度,则抛出
IndexOutOfBoundsException

在你的例子中,如果你只是简单地将
c
c
长度-1变为
0
,这是你的
最后一个索引
。而且你的
第一个索引
也是
0
。这就是你得到
索引自动边界感知的原因


希望您能理解。

您应该将代码放在一个try-catch语句中,该语句是生成此异常的输入?使用调试器,您会发现为什么会出现此异常焦点在这一行:
intString=userInput.substring(0,长度-1)并在这一行
charscale=userInput.charAt(长度-1)。在调用这些方法之前,您需要检查
length
值。我通过输入100d得到错误,然后会出现错误:无效的临时框和一个更正临时单位的请求,我这样做了,然后得到了所需的结果,但错误弹出。在我输入新的输入之前,这些代码都不应该运行吗?您应该将代码放在一个try-catch语句中,该语句是生成此异常的输入。使用调试器,您会发现为什么会出现此异常。请关注这一行:
intString=userInput.substring(0,长度-1)并在这一行
charscale=userInput.charAt(长度-1)。在调用这些方法之前,您需要检查
length
值。我通过输入100d得到错误,然后会出现错误:无效的临时框和一个更正临时单位的请求,我这样做了,然后我得到了所需的结果