【问题标题】:New to Java, Do-While Loop IssuesJava 新手,Do-While 循环问题
【发布时间】:2016-01-03 23:02:33
【问题描述】:

我对 Java 比较陌生,我在运行这个 do-while 循环时遇到了一些麻烦。

问题 1

编写一个程序,允许用户转换给定的温度 摄氏度到华氏度或华氏度到摄氏度。 使用以下公式:Degrees_C = 5 (Degrees_F − 32) / 9 Degrees_F = (9 (Degrees_C) / 5) + 32 提示用户输入 温度,C 或 c 表示摄氏温度,F 或 f 表示 华氏度。如果摄氏度是,将温度转换为华氏度 输入,如果输入华氏温度,则为摄氏温度。显示结果 一种可读的格式。如果输入 C、c、F 或 f 以外的任何内容, 打印错误消息并停止。

问题 2

让我们继续问题 1,但使用循环,以便用户可以转换其他 温度。如果用户输入 C 或 F 以外的字母——在任一 大写或小写—温度后,打印错误消息并 要求用户重新输入有效的选择。每次转换后,询问 用户键入 Q 或 q 退出或按任何其他键重复 循环并执行另一个转换

public class Lab_4 {

    public static void main(String arg[]) {
        Scanner input = new Scanner(System.in);
        double F; //Fahrenheit
        double C; //Celsius
        String method; 
        boolean keepGoing = true; 
        do {            
            System.out.println("Choose a method:  ");
            System.out.println("(F)  Fahrenheit to Celsius.  ");
            System.out.println("(C)  Celsius to Fahrenheit.  ");
            System.out.println("(Q)  Exit the loop.  ");
            method = input.nextLine();
            if (method.charAt(0) == 'f' || method.charAt(0) == 'F') {
                System.out.println("Method F");
                System.out.println("Enter the temperature in Fahrenheit:  ");
                F = input.nextDouble();
                C = 5 * (F - 32) / 9;
                System.out.println("Temperature in Celsius:  " + C); }
            if (method.charAt(0) == 'c' || method.charAt(0) == 'C') {
                System.out.println("Method C");
                System.out.println("Enter the temperature in Celsius:  ");
                C = input.nextDouble();
                F = (9 * C / 5) + 32;
                System.out.println("Temperature in Fahrenheit:  " + F); }
            if (method.charAt(0)== 'q' || method.charAt(0)== 'Q') {
                keepGoing = false; 
                System.out.println("Exiting the loop!  "); }
            else {
                //if index 0 doesn't equal to C, F, Q, it's out of range. 
                System.out.println("Method is out of range!  ");
            }
        }while(keepGoing = true);
        input.close();
    }
}

循环将继续进行,直到我输入 Q 或 q 退出。所以我必须输入 Q 才能退出循环,但在我得到转换值后立即收到一条错误消息,它根本没有通过循环。该程序只是不通过while循环。

enter image description here

尝试 2,仍然错误

package Lab_4;

import java.util.Scanner;

    public class Lab_4 {

        public static void main(String arg[]) {
            Scanner input = new Scanner(System.in);
            double F; //Fahrenheit
            double C; //Celsius
            String method; 
            boolean keepGoing = true; 
            do {            
                System.out.println("Choose a method:  ");
                System.out.println("(F)  Fahrenheit to Celsius.  ");
                System.out.println("(C)  Celsius to Fahrenheit.  ");
                System.out.println("(Q)  Exit the loop.  ");
                method = input.nextLine();
                if (method.charAt(0) == 'f' || method.charAt(0) == 'F') {
                    System.out.println("Method F");
                    System.out.println("Enter the temperature in Fahrenheit:  ");
                    F = input.nextDouble();
                    C = 5 * (F - 32) / 9;
                    System.out.println("Temperature in Celsius:  " + C); }
                else if (method.charAt(0) == 'c' || method.charAt(0) == 'C') {
                    System.out.println("Method C");
                    System.out.println("Enter the temperature in Celsius:  ");
                    C = input.nextDouble();
                    F = (9 * C / 5) + 32;
                    System.out.println("Temperature in Fahrenheit:  " + F); }
                else if (method.charAt(0)== 'q' || method.charAt(0)== 'Q') {
                    keepGoing = false; 
                    System.out.println("Exiting the loop!  "); }
                else {
                    //if index 0 doesn't equal to C, F, Q, it's out of range. 
                    System.out.println("Method is out of range!  ");
                }
            }while(keepGoing);
            input.close();
        }
    }

【问题讨论】:

  • 尝试将第二个和第三个 ifs 更改为 else if
  • 如果放 if else 而不是 if 并修复 while(keepGoing),但程序仍然没有读取,因为 Java 显然无法读取字符串索引(超出范围)。

标签: java loops while-loop boolean


【解决方案1】:

你有一个错字:

}while(keepGoing = true);

应该是:

}while(keepGoing == true);

或者只是:

}while(keepGoing);

说明

keepGoing = true,即使在条件内,也会将keepGoing 分配给true 并返回其值(在这种情况下始终为true)。

另一方面,keepGoing == true 要求比较 keepGoingtrue 的值是否相等。

【讨论】:

  • 我要补充一点,这实际上应该是 while (keepGoing) 以获得更好的代码。我会添加一个逗号:)
  • 不仅仅是为了更好的代码。为了避免这个潜在的问题,应该避免比较布尔值。
  • 虽然您正确解释了为什么需要更正 while 条件,但这并不能回答 OP 的原始问题。 (尽管它可能会回答未来的问题。)
  • 如果您认为他们有错字,请投票关闭。
  • @lilezek 如果是这种情况,您的回答不正确。非终止的 while 循环本身不会导致错误;它只会永远持续下去(这是一个逻辑错误,而不是编译或运行时错误)。他收到错误的原因是因为他输入了一个空白字符串作为输入,您可以在他附加到问题的屏幕截图中看到。
【解决方案2】:

代码逻辑错误

While 循环

您的 while 循环在每次迭代后将 keepGoing 分配为 true。这意味着您的循环将永远持续下去。由于您在任何条件下都不break,我假设您不希望这种行为。

If 语句

您的 if 语句会导致错误,因为它们不相互依赖。你目前的写法是这样的(简化的):

if (method.charAt(0) == 'some_letter')
    // do something
if (method.charAt(0) == 'some_other_letter')
    // do something else
else
    // show error

问题在于第一个 if 条件的检查独立于第二个。这意味着如果您的第一个条件 (method.charAt(0) == 'some_letter') 为真,您仍然会收到错误消息,因为“else”与第二个 if 语句相关联,这将是假的(因为第一个字符不能是两个不同的字符)。

正确的写法是这样的(再次简化):

if (method.charAt(0) == 'some_letter')
    // do something
else if (method.charAt(0) == 'some_other_letter') // NOTE the else on this line
    // do something else
else
    // show error

这样做会将所有条件联系在一起,因此只执行其中一个条件。

扫描仪问题

至于您收到的实际错误消息:这是因为 method 是一个空白字符串。空白字符串的长度为 0,因此使 0 成为无效索引,因此 method.charAt(0) 将导致 StringIndexOutOfBounds 错误。

但是为什么method 在运行第一个循环后是空白的?好吧,对于初学者来说,这有点“陷阱”。 Scanner.nextLine() 将检索当前行的其余部分。就扫描仪而言,一个“行”是直到下一个换行符(按下回车时得到的隐藏字符...\n)之前的所有内容。另一方面,Scanner.nextDouble() 只抓取下一个数字......但不消耗换行符。

您的程序中发生的情况是,一旦您提示用户输入要转换的值,它就会添加一个不会被消耗的额外换行符。让我们通过一个简化的例子:

do {
    System.out.println("Choose your method")
    method = Scanner.nextLine(); 

    // User enters "f", then presses enter. This means the Scanner's buffer
    // contains "f\n". nextLine will read everything up to "\n" (which is everything)
    // then consumes the newline character. Afterwards, the Scanner's buffer 
    // is completely empty. 

    if ((method.charAt(0) == 'f') || (method.charAt(0) == 'F'))
    {
        double F = Scanner.nextDouble();

        // User enters "12", then presses enter. The Scanner's buffer now contains
        // "12\n". nextDouble will read in "12", but will NOT consume the 
        // newline character. Afterwards, the Scanner's buffer will contain "\n".
    }

    // Loop ends here. You start from the top and call Scanner.nextLine.
    // However, the Scanner's buffer still has "\n" at this point, so 
    // nextLine will grab everything up to the newline (in other words, a blank string)
    // and then consume the already existing newline. Since you do no error
    // checking to make sure method has length > 0, your program crashes.
}

那么你如何解决这个问题?这实际上很容易。调用Scanner.nextDouble() 后,只需调用Scanner.nextLine() 即可使用换行符。

此外,我建议添加检查以确保用户的输入有效(即,不是空字符串)。这样,您的程序就不会崩溃。

有关更多信息和/或更好的解释,请参阅以下问题:Skipping nextLine() after using next(), nextInt() or other nextFoo() methods

【讨论】:

  • @Y.Chen 防止它的唯一方法是防止无效输入。我会这样做的方式是在任何其他语句之前添加一个 if 语句:if (method.length() == 0) continue;。该语句将简单地跳过循环的一次迭代,这意味着在用户输入长度大于无的输入之前,什么都不会显示。或者,您可以显示错误、使用一些默认值或执行您认为对您的程序合乎逻辑的任何其他操作,而不是继续。
  • @Y.Chen 请看我编辑的答案。您遇到的问题与Scanner.nextDouble() 有关...幸运的是,修复它非常简单。
【解决方案3】:

keepGoing = true 是 Java 中的赋值,不是布尔条件,改为 keepGoing == true,或者简单的while(keepGoing )

【讨论】:

    【解决方案4】:

    indexOutOfBoundsException 是由于您的案例“方法”中的空字符串

    method.charAt(0)
    

    为避免这种情况,您可以在从控制台获取输入后立即放置

    method = input.nextLine();
    

    然后在if语句下面添加

    if(!method.equals(""))
    

    或者检查字符串的长度

    if(method.length() > 0)
    // your code goes here
    

    此外,while 语句将值“true”分配给布尔值“keepgoing”,而不是它应该是

    while(keepgoing)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多