【问题标题】:Else If and Do while does not work as intendedElse If 和 Do while 不能按预期工作
【发布时间】:2012-03-09 10:45:00
【问题描述】:

编辑:我最近编译一个我知道无法编译的程序让我相信我的编译器同时有问题。毫无疑问是因为我在 Mac 上的 WINE 中运行它而不是原生应用程序。谢谢你的回复。当我用编译器修复上述错误或将计算机移到一台可以正常工作的计算机时,我将正确测试所有响应并进行所有更改。

我对编程和这个网站都比较陌生,所以请多多包涵。我的两个 If 语句和一个 do/while 出现错误,我无法解决。

整个程序按预期工作,但下面有两个块。问题是,当我输入字符 'y' 时,一切都按预期工作,并且 ("Results=" + Arrays.toString(row)) 会按预期打印。它还继续通过原始的 For 循环并再次启动程序。

但是,当我输入任何其他字符(即不是 'y' 或 'n')时,代码不会打印“输入必须是 'y' 或 'n'”,而只是等待另一个输入。即使输入了“n”,它也不会按照我的意愿退出循环,它只是继续循环而不是继续循环,如果我认为它会继续。它无限期地执行此操作,不接受除 'y' 之外的任何其他输入以继续通过循环,因此我永远无法收到打印“负数”。

有人对为什么会发生这种情况有任何想法吗? 虽然在技术上不是家庭作业,但我将其标记为我想知道(如果可能的话)发生了什么,而不是仅仅如何解决它。

        do {
            ans = input.next().charAt(0);
                if (!ans.equals('y')  ||  !ans.equals('n')) {
                    System.out.println ("Input must be either 'y' or 'n'");
                }
        } while (!ans.equals('y')  ||  !ans.equals('n'));

和

if (ans.equals('y')) {
            for (Object[] row : prevResults) {
                    System.out.println("Results = " + Arrays.toString(row));
            }
        } //
        else if (ans.equals('n')) {
            System.out.println("Negative");
            //System.exit(0); 
        }

完整代码如下

import java.util.*;

public class Averages {
    public static void main (String [] args) {

        //declare variables
        int course, exam, average = 0;
        char ans;
        String pass;

        //creating objects
        Scanner input =  new Scanner(System.in);
        List<Object[]> prevResults = new ArrayList<Object[]>();

        //full loop
        for (int i = 0; i < 5; i++ ) {

            System.out.println ("Loop " + (++i) + " out of 5");

            //Course loop
            do {
            System.out.println ("Please enter a course mark out of 100");
            course = input.nextInt();
                if (course > 100) {
                    System.out.println ("Number entered is over 100");
                }
            } while (course > 100);

            //Exam loop
            do {
            System.out.println ("Please enter an exam mark out of 100");
            exam = input.nextInt();
                if (exam > 100) {
                    System.out.println ("Number entered is over 100");
                }
            } while (exam > 100);


            average = (course + exam)/2;

            // Final Grade
            System.out.println ("The average mark is " + average);

            if ( average >= 50 && course > 40 && exam > 40)  {
                System.out.println ("The final grade is pass");
                pass = "Pass";
            }
            else {
                System.out.println ("The final grade is fail");
                pass = "Fail";
            }

            //add to array
            prevResults.add(new Object[] { "Course mark: " + course, "Exam mark: " + exam,"Average: " + average, "Grade: " + pass});


            System.out.println ("Would you like to see previous results? y/n");


            //'Previous results' question loop
            do {
                ans = input.next().charAt(0);
                    if (!ans.equals('y')  ||  !ans.equals('n')) {
                        System.out.println ("Input must be either 'y' or 'n'");
                    }
            } while (!ans.equals('y')  ||  !ans.equals('n'));


            // Close or Array if statement
            if (ans.equals('y')) {
                for (Object[] row : prevResults) {
                        System.out.println("Results = " + Arrays.toString(row));
                }
            } //
            else if (ans.equals('n')) {
                System.out.println("Negative");
                //System.exit(0); 
            }
        }// end for 
    }//end main
}//end class

编辑 2: 我已经切换了计算机,并且所有建议的答案都确实有效。他们是

while (ans != 'y' && ans != 'n');

与

while (!(ans.equals('y')  ||  ans.equals('n')));

与

按照 Chris Browne 的建议制作单独的方法。

为了其他阅读本文的人的利益,这些解决方案非常有效,尽管我没有时间查看 Greg Hewgill 建议的 BufferedReader 我很可能会实施它,因为从他所说的来看,这似乎是一个更好的选择.

【问题讨论】:

  • 您对Scanner 的使用容易出现错误和意外结果,尤其是在交互式程序中。你必须使用Scanner吗?你考虑过替代品吗?例如,BufferedReader 有一个 readLine() 方法。
  • 老实说,我不知道有任何替代方案。有人告诉我,这种方法适用于辅导讲师的阅读,所以我没有考虑太多替代方案。正如我所说,我对编程相当陌生。我会调查 BufferedReader 看看它是否提供了解决方案。

标签: java if-statement nested while-loop


【解决方案1】:

首先,您的代码中有一个错误:

System.out.println ("Loop " + (++i) + " out of 5");

您不应增加 i,因为它已经在您的 for 更新语句中增加 - 结果是您得到错误的迭代计数。

接下来,您的不应该使用equals 来比较char 的值 - 请改用==。当您使用equals 时,由于auto-boxing,会发生很多不必要的事情,最终导致大致characterObject.equals(anotherCharacterObject),对象类型为java.lang.Character。只需使用例如ans == 'y' 代替。

最后,正如人们所指出的,你应该将你的 do-while 重写为:

do {
    ans = input.next().charAt(0);
    if (ans != 'y' && ans != 'n') {
        System.out.println ("Input must be either 'y' or 'n'");
    }
} while (ans != 'y' && ans != 'n');

甚至有单独的条件检查方法(感谢 Chris Browne)。

【讨论】:

  • 啊,这很有帮助。我最初使用的是字符串而不是 Char,但我不得不更改它,因为字符串读取我的“输入”作为字符时出现错误。我不知道 == 也可以与 Char 一起使用,因为我发现它没有与字符串 :P 我将按照建议重写我的 do-while 并查看它是否产生结果。
【解决方案2】:

条件应该是:

while (!(ans.equals('y')  ||  ans.equals('n')));

因为你第一次写的条件:

while (!ans.equals('y')  ||  !ans.equals('n'));

总是等于true(每个字符都不是y或n)。

感谢De Morgan,另见my answer here。

【讨论】:

  • 我当时尝试了这个解决方案,但它似乎没有改变任何东西,它仍然对“y”以外的任何东西都有一个无限循环。也许还有其他不正确的地方?
  • 经过进一步检查,我的编译器并没有编译我当前的工作,而是它的以前版本,切换到另一台计算机,这种方法确实按预期工作。谢谢你的回答。
【解决方案3】:

你的情况需要

if (!ans.equals('y')  &&  !ans.equals('n'))

而不是

if (!ans.equals('y')  ||  !ans.equals('n'))

【讨论】:

    【解决方案4】:
      } while (!ans.equals('y')  ||  !ans.equals('n'));
    

    说 While ans 不等于 'y' 或 while ans 不等于 'n'。这将永远是正确的(它永远不等于其中之一)

    【讨论】:

      【解决方案5】:

      你的条件逻辑是相反的,你是说:

      if (!ans.equals('y') || !ans.equals('n'))
      

      从语义上讲,这是一个非常难以解析的行,因为您在说“如果答案不是 y 或答案不是 n”,这是单个语句中的许多逻辑运算符。这可能就是您的错误蔓延的原因。

      确实,快速解决方法是将“或”替换为“与”,但这并不能真正帮助您理解问题。您应该重构它以使用不同的方法,例如:

      if(isLegalAnswer(ans))
      

      其中 isLegalAnswer 定义为:

      private static boolean isLegalAnswer(char ans) {
        return (ans=='y' || ans=='n');
      }
      

      这允许您使用单个否定来否定整个表达式 (!isLegalAnswer(ans))。

      通常,我禁止自己在单个语句或表达式中使用多个否定,这有助于使代码易于阅读,同时对执行速度几乎没有影响。

      【讨论】:

      • 感谢您的回复。真正理解我为什么错了是非常有帮助的。
      猜你喜欢
      • 1970-01-01
      • 2020-11-28
      • 1970-01-01
      • 2016-06-11
      • 1970-01-01
      • 2020-03-11
      • 2013-12-16
      • 1970-01-01
      • 2020-04-09
      相关资源
      最近更新 更多