简体   繁体   English

java do while循环在满足条件后保持循环

[英]java do while loop keeps looping after condition is met

I am a new java programmer and I am writing a program that sets 3 model numbers for 3 printers. 我是一名新的Java程序员,正在编写为3台打印机设置3个型号的程序。 If user inputs wrong values I want it to continue asking user for the model number. 如果用户输入了错误的值,我希望它继续询问用户型号。 I got it to work but only if the first value the user inters the the number for one of the 3 printers. 我让它工作,但前提是用户将第一个值插入3台打印机之一的编号中。 if the first value is not one of the possible values and the second input is it still keeps repeating the loop. 如果第一个值不是可能的值之一,而第二个输入是第二个输入,则它将继续重复循环。

package printing;

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

        System.out.print("Model Number:");
        String modelNumber = s.nextLine();
        // increment count if first input value is wrong
        if (!s.equals(machine1) || !s.equals(machine2) || !s.equals(machine3))
            count++;

        // if user inputs right value
        while (true) {
            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;
            }

            // keep looping if user does not input values for machine1, machine2 or machine3
            do {
                System.out.println("Try again");
                System.out.print("Model Number:");
                String modelNumberFalse = s.nextLine();
                /* each time user gets value wrong the count variable goes up by 1 and
                   the loop breaks when count reaches 3 */
                count++;
                if (count == 3)
                    break;
            } while (!s.equals(machine1) || (!s.equals(machine2)) || (!s.equals(machine3)) && (count < 2));

        }
    }
}

Also each time the user inputs the wrong value I want the count variable to increment until it reaches 3 and the do while loop breaks but it keeps asking for the model number after I've entered the wrong values more than 3 times. 同样,每次用户输入错误的值时,我都希望count变量增加直到它达到3并且do while循环中断,但是在我输入错误的值超过3次之后,它会不断询问型号。

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. s是扫描器,而不是字符串,这不是有效的比较。 Substituting modelNumber for s gives: modelNumber代替s得到:

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. 除非modelNumber,machine1,machine2和machine3都具有相同的值,否则不能为false。

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;" 另外,如果用“ return”代替“ break”; along with making the change to the do-while condition, it works. 并更改了do-while条件,它可以正常工作。 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. 在内部do-while中调用break会使控件返回到外部while循环的顶部。 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. 添加一个在中断之前设置的布尔标志,并在外部while循环中对其进行测试将是解决此问题的一种方法。 Or just use return. 或者只是使用return。

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 希望这能解决您的问题

  • First: you use NOT OR when you need NOT AND 首先:您可以使用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");
                }
            }

        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM