【问题标题】:java do while loop keeps looping after condition is metjava do while循环在满足条件后不断循环
【发布时间】:2015-07-21 20:21:40
【问题描述】:

我是一名新的 Java 程序员,我正在编写一个程序,为 3 台打印机设置 3 个型号。如果用户输入错误的值,我希望它继续向用户询问型号。我让它工作,但前提是用户的第一个值是 3 台打印机之一的编号。如果第一个值不是可能的值之一,而第二个输入是它仍然不断重复循环。

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

        }
    }
}

此外,每次用户输入错误的值时,我都希望计数变量递增,直到达到 3 并且 do while 循环中断,但在我输入错误值超过 3 次后,它一直在询问型号。

【问题讨论】:

  • 如何在一个while循环中编写它?谢谢

标签: java loops do-while


【解决方案1】:

有几个问题。这一行是错误的:

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

s 是 Scanner,而不是 String,这不是有效的比较。用modelNumber 代替s 得到:

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

这不能为假,除非 modelNumber、machine1、machine2 和 machine3 都是相同的值。

另外,测试计数会搞砸这一切,而且是多余的,因为您正在测试它并在循环中中断。

应该是

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

DeMorgan's Laws。应用这条规则给出了

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

这可能更容易阅读。

另外,如果你用“return”代替“break;”随着对 do-while 条件的更改,它可以工作。所以还有其他事情发生。在内部 do-while 中调用 break 会导致控制返回到外部 while 循环的顶部。添加一个在中断之前设置并在外部 while 循环中测试的布尔标志将是解决此问题的一种方法。或者只使用 return。

【讨论】:

  • 或者更好的是,删除否定并使用 or,根据德摩根法律
  • 好吧,您可以将固定代码缩减为:“应该是:while(true);。那是一样的,并且不会解决 OPs 问题。
  • 如果不清楚我的意思:每个比较都是 false 并且由于否定,“结果”将是 while(true &amp;&amp; (true) &amp;&amp; (true))while(true)。如果这是有意为之,则应将其替换为简单的 while(true) 循环。
  • @NathanHughes 如果我看到您的建议并且看到您仍然将ScannerString 进行比较,那么我知道每个比较都是错误的。而且由于您否定每个比较,最后您会得到while(true)。德摩根定律在这里并不重要......或者至少在你修正了错误的比较之前:)。
  • @NathanHughes 谢谢:)。
【解决方案2】:
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");

        }
    }
}

希望这能解决你的问题

【讨论】:

    【解决方案3】:
    • 首先:在需要 NOT AND 时使用 NOT OR
    • 第二:你在重复 没有正当理由的测试

    在您的代码中,您最终会重复相同的测试。这意味着,当您添加机器时,您将不得不在多个地方更新您的代码。

    软件的第一条规则是不要重复自己。当下一个人被要求对条件进行判断时,他/她会找到第一个代码块并对其进行编辑,并且可能永远不会注意到重复的代码块。复制粘贴的代码是根源或许多未来的错误。

    您可以像这样简化代码,使每次检查只进行一次:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-26
      相关资源
      最近更新 更多