否则If和Do while不能按预期工作

时间:2012-03-09 10:45:01

标签: java if-statement nested while-loop

编辑:我最近发生的编译程序的事件,我知道无法编译,这让我相信我同时遇到了编译器的问题。毫无疑问,由于我在Mac上的WINE中运行它而不是本机应用程序。谢谢你的回复。我将正确测试所有响应并在我使用编译器修复错误时进行所有更改,或者我已将计算机移动到具有工作计算机的计算机。

我对编程和本网站都比较陌生,所以请耐心等待。我的两个If语句和一个/我无法解决的错误。

整个程序按预期工作,但下面是两个块。问题是,当我输入字符'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');

AND

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

AND

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

为了其他任何阅读此内容的人的利益,这些解决方案运行得非常好,尽管我没有时间查看Greg Hewgill建议的BufferedReader我很可能会实现它,因为它似乎是一个更好的选择,因为它已经说明了

5 个答案:

答案 0 :(得分:4)

首先,代码中出错:

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)。

答案 1 :(得分:2)

条件应该是:

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

因为你第一次写的条件是:

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

始终等于true(每个字符不是y或不是n)。

感谢De Morgan,也请my answer here

答案 2 :(得分:1)

您的病情需要

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

而不是

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

答案 3 :(得分:1)

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

虽然ans不等于'y'或者ans不等于'n'。这将永远是真的(它总是不等于其中之一)

答案 4 :(得分:1)

你的条件逻辑是颠倒的,你说:

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))。

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