Else If and Do while does not work as intended

家住魔仙堡 提交于 2019-12-24 16:09:28

问题


EDIT: Recent happenings of me compiling a program I know could not compile lead me to believe I am simultaneously having an issue with my compiler. No doubt due to my running it in WINE on mac as opposed to a native application. Thank you for your responses. I will properly test out all responses and make all changes when I have fixed said error with compiler or I have moved computers to one with a working one.

I am relatively new to programming and also this website so please bear with me. I am getting an error with my two of my If statements and one do/while that I am unable to resolve.

The entire program works as intended but two blocks which are below. The problem is that when I enter the character 'y', everything works as intended and the ("Results =" + Arrays.toString(row)) prints as I expected it to. It also proceeds to continue through the original For loop and start the program again.

However, when I enter any other character, (i.e not 'y' or 'n') the code does not print "Input must be either 'y' or 'n'" and just waits for another input. Even when 'n' is entered, it does not follow out of the the loop as I wanted, it just continues to loop and not proceed to the else if I had thought it would. It does this indefinitely, not accepting any other input than 'y' to continue passed the loop so I can never receive the print "negative".

Does anyone have any thoughts as to why this is happening? While not technically homework, I tagged it as such as I want to know, if possible, what is happening as opposed to just how to fix it.

        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'));

and

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); 
        }

Full code is as below

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

EDIT 2: I have switch computers and all the suggested answers to indeed work. They being

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

AND

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

AND

Making a separate method as suggested by Chris Browne.

For the benefit of anyone else who reads this, these solutions work wonderfully although I have not had time to look at the BufferedReader suggested by Greg Hewgill I will most likely implement it because it seems like a better option from what he has stated.


回答1:


First, an error in your code:

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

You should not increment i as it is already incremented in your for update statement - you are getting the wrong iteration count as a result.

Next, your should not use equals to compare char values - use == instead. When you use equals, a lot of unnecessary things happen due to the auto-boxing, that ultimately result in roughly characterObject.equals(anotherCharacterObject), objects being of type java.lang.Character. Just use e.g. ans == 'y' instead.

Last, as folks have pointed out, you should rewrite your do-while as:

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');

or even have a separate method for the condition check (thanks to Chris Browne).




回答2:


The condition should be:

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

because the condition you first wrote:

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

always equals to true (every character is not y or not n).

And say thanks to De Morgan, also see my answer here.




回答3:


Your condition needs to be

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

instead of

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



回答4:


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

says While ans is not equal to 'y' or while ans is not equal to 'n'. This will always be true (it will always be not equal to one of them)




回答5:


Your conditional logic is reversed, you're saying:

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

Semantically, this is a very difficult line to parse, because you're saying "if answer isn't y or answer isn't n", which is a lot of logical operators in a single statement. This is probably why your error has crept in.

Really, the quick-fix is to swap the "or" for an "and", but that won't really help you understand the problem. You should refactor it to use a different approach, such as:

if(isLegalAnswer(ans))

where isLegalAnswer is defined as:

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

This allows you to negate the whole expression (!isLegalAnswer(ans)) using a single negation.

Conventionally, I forbid myself from using more than one negation in a single statement or expression, this helps to keep code easy to read while making little or no difference to speed of execution.



来源:https://stackoverflow.com/questions/9632725/else-if-and-do-while-does-not-work-as-intended

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!