java do while loop keeps looping after condition is met

前端 未结 3 2034
自闭症患者
自闭症患者 2021-01-27 00:32

I am a new java programmer and I am writing a program that sets 3 model numbers for 3 printers. If user inputs wrong values I want it to continue asking user for the model numbe

相关标签:
3条回答
  • 2021-01-27 00:36
    • First: you use NOT OR when you need NOT AND
    • Second: You are repeating the test for no good reason

    In your code, you end up having the same test repeated. This means, as you add machines, you will have to update your code in multiple places.

    First rule of software is to not repeat yourself. When the next guy is asked to chance the conditions, he/she will find the first block of code and edit it and probably never notice the repeated block. Copy pasted code is the root or many future bugs.

    You could simplify your code to having each check only once like this:

    import java.util.Scanner;
    
    public class newClass {
    
        public static void main(String[] args) {
    
            int count = 0;
    
            // for extra credit, try to make this an ArrayList
            // so you can keep adding models as needed
            // then you would adjust your tests to leverage the ArrayList
            // search functions
            String machine1 = "546";
            String machine2 = "892";
            String machine3 = "127";
    
    
            Scanner s = new Scanner(System.in);
    
            // when using a while loop, it is good practice to use a boolean
            // as your logic expands, multiple tests in the loop may set the
            // boolean to true or false
            // it is cumbersom to have large blocks of code in your while check
            boolean keepOnTrucking = true;
    
            System.out.print("Enter Model Number:");
            while (keepOnTrucking) {
    
                String modelNumber = s.nextLine();
    
                // when using multiple tests, it is good
                // to give each test its own line and end the line
                // with the logical operator that joins it to the next
                // it makes it easier to read
                // and easier to edit (add or remove tests)
    
                // Logical operator note:
                // Your test was: not A OR not B OR not C
                // This would NEVER work, as A != B != C
                // If a user entered machine2, the check would
                // fail for !(machine1), OR !(machine2) OR !(machine3)
                // because while (!s.equals(machine2)) would say false
                // (!s.equals(machine1)) would say true, and the OR
                // chain would stop and count it as an error.
                // Instead you want:
                // !(machine1) && !(machine2) && !(machine3)
                // Thus to to error, it has to not any of the machines.
                // If it is true for all three nots, then you have an error
                if (!machine1.equals(modelNumber) && 
                    !machine2.equals(modelNumber) &&
                    !machine3.equals(modelNumber)) {
    
                    // you only increment on failure
                    count++;
    
                    // nice developers give meaningful feed back to users
                    if (count>=3) {
                        System.out.print("Out of guesses! Go Away!"); // even when it is mean
    
                        // since you are nested in one while loop,
                        // this will break you out
                        break;
                    } else {
                        System.out.print("Not a valid model number, please re-enter:");
                    }
                } else {
    
                    // the found a machine, so exit the while loop
                    keepOnTrucking = false;
    
                    if (machine1.equals(modelNumber)) {
                        System.out.println("Machine 1 is online");
                    } else if (machine1.equals(modelNumber)) {
                        System.out.println("Machine 2 is online");
                    } else { // since this ins the only one left, you don't need an if clause
                        System.out.println("Machine 3 is online");
                    }
                }
    
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-27 00:39
    import java.util.Scanner;
    
    public class newClass
    {
    
        public static void main(String[] args)
        {
            int count = 0; 
            String machine1 = "546";
            String machine2 = "892";
            String machine3 = "127";
    
            Scanner s = new Scanner(System.in);
    
            while (true)
            {
                System.out.print("Model Number:");
                String modelNumber = s.nextLine();
                // increment count if first input value is wrong
                if ((!modelNumber.equals(machine1)) || (!modelNumber.equals(machine2)) || (!modelNumber.equals(machine3)))
                    count++;
    
                if (count == 3)
                {
                    System.out.println("You have utilized your maximum number of try's");
                    break;
                }
    
                if (modelNumber.equals(machine1))
                {
                    System.out.println("Machine 1 is online");
                    break;
                }
                if (modelNumber.equals(machine2))
                {
                    System.out.println("Machine 2 is online");
                    break;
                }
                if (modelNumber.equals(machine3))
                {
                    System.out.println("Machine 3 is online");
                    break;
                }
    
                System.out.println("Try again");
    
            }
        }
    }
    

    Hope this solves your question

    0 讨论(0)
  • 2021-01-27 00:49

    There are several problems. This line is wrong:

    while(!s.equals(machine1) || (!s.equals(machine2)) || (!s.equals(machine3)) && (count < 2));
    

    s is a Scanner, not a String, this isn't a valid comparison. Substituting modelNumber for s gives:

    while(!modelNumber.equals(machine1) || (!modelNumber.equals(machine2)) || (!modelNumber.equals(machine3)) && (count < 2));
    

    This can't be false unless modelNumber, machine1, machine2, and machine3 are all the same value.

    Also testing count is messing this up and is redundant since you're testing it and breaking within the loop.

    It should be

    while(!modelNumber.equals(machine1) 
        && (!modelNumber.equals(machine2)) 
        && (!modelNumber.equals(machine3)));
    

    See DeMorgan's Laws. Applying this rule gives

    while(!(modelNumber.equals(machine1)
        || modelNumber.equals(machine2)
        || modelNumber.equals(machine3)))
    

    which may be easier to read.

    Also, if you substitute "return" for "break;" along with making the change to the do-while condition, it works. So there is something else going on. Calling break in the inner do-while causes control to return to the top of the outer while loop. Adding a boolean flag that is set before you break and which is tested in the outer while loop would be one way to solve this. Or just use return.

    0 讨论(0)
提交回复
热议问题