Java中的无限While循环

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2342633/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 06:22:41  来源:igfitidea点击:

Infinite While Loop in Java

javawhile-loopinfinite-loop

提问by Andy

Hey there! I'm trying to do some data input validation but I haven't been able to figure it out. I'm getting an infinite while loop in when I try to validate if the first character entered is a letter. . . .

嘿!我正在尝试进行一些数据输入验证,但我一直无法弄清楚。当我尝试验证输入的第一个字符是否为字母时,我得到了一个无限的 while 循环。. . .

Thanks for your help!

谢谢你的帮助!

public class methods
{
    public static void main(String args[]) throws IOException
    {
        String input ="";
        int qoh=0;
        boolean error=true;

        Scanner keyboard = new Scanner (System.in);

        //while (error)
        //{
            //error=true;

        while (error==true)
        {
           System.out.print("\nEnter Quantity on Hand: ");
           input = keyboard.nextLine();

           if (input.length() <1)
           {
               System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500");
               error=true;
               System.out.println(qoh);
               System.out.println(input);
            }
            else
            {
                error=false;
            }
        }

        error = true;

        while (error==true)
        {
            if (Character.isLetter(input.charAt(0)))
            {
                System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500");
                error=true;
                System.out.println(qoh);
                System.out.println(input);
             }
             else
             {
                 qoh = Integer.parseInt(input);
                 error=false;
              }
          }
      }
  }

回答by Fortega

You don't have an input = keyboard.nextLine();in your second while loop.

input = keyboard.nextLine();的第二个 while 循环中没有。

You could refactor your code to only ask for new input when there is an error. So right after the sysout of 'ERROR...'

您可以重构代码以仅在出现错误时请求新输入。所以就在 'ERROR...' sysout 之后

Extra: I would actually do this different. The 'error = true' at the beginning is a bit confusing, because there might not be an error.

额外:我实际上会这样做。开头的 'error = true' 有点混乱,因为可能没有错误。

You could for example write a method called tryProcessLine, which reads the input and returns true if ok and false if there was an error, and than just do something like while(!tryProcessLine()){ }

例如,您可以编写一个名为 tryProcessLine 的方法,该方法读取输入并在确定时返回 true,如果出现错误则返回 false,而不仅仅是执行类似的操作 while(!tryProcessLine()){ }

Working example below:

下面的工作示例:

import java.io.IOException;
import java.util.Scanner;

public class Methods {

  private static int qoh;

  public static void main(String args[]) throws IOException {

    while (!tryProcessLine()) {
        System.out.println("error... Trying again");
    }

    System.out.println("succeeded! Result: " + qoh);

  }

  public static boolean tryProcessLine() {

    String input = "";

    Scanner keyboard = new Scanner(System.in);

    System.out.print("\nEnter Quantity on Hand: ");

    input = keyboard.nextLine();

    try {
        qoh = Integer.valueOf(input);

        if (qoh < 0 || qoh > 500) {
          System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500");
          return false;
        } else {
          return true;
        }
    } catch (NumberFormatException e) {
        System.out.println("\n**ERROR06** - Quantity on hand must be numeric");
        return false;
    }
  }
}

回答by Adamski

The infinite loop occurs because the second while loop is repeatedly checkingwhether the first character in the String (input.charAt(0)) is a letter. Assuming that the result from this check is true the loop will never terminate.

发生无限循环是因为第二个 while 循环反复检查String ( input.charAt(0)) 中的第一个字符是否为字母。假设此检查的结果为真,循环将永远不会终止。

Your code could be simplified to something like:

您的代码可以简化为:

Integer qty = null;

while (scanner.hasNext() && qty == null) {
  String line = scanner.next();
  try {
    qty = Integer.parseInt(line);
  } catch(NumberFormatException ex) {
    System.err.println("Warning: Ignored non-integer value: " + line);
  }
}

if (qty == null) {
  System.err.println("Warning: No quantity specified.");
}

回答by Kylar

If it is a character, you're allowing error to still = true, which is causing that loop to continue forever, you're not ever going back to the beginning and reading another line.

如果它是一个字符,则您允许错误仍然 = true,这将导致该循环永远继续,您永远不会回到开头并阅读另一行。

Here is some code that does what you want and is structured a little better.

这里有一些代码可以做你想要的,并且结构更好一点。

public class ScanInfo {

  Scanner keyboard = new Scanner(System.in);

  public ScanInfo(){
    String line = getLineFromConsole();
    while(null != line && !"quit".equals(line)){
      if(isValidInput(line)){
        int validNumber = Integer.parseInt(line);
        System.out.println("I recieved valid input: "+validNumber);
      }else{
        System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500");
      }
      line = getLineFromConsole();
    }

  }

  private boolean isValidInput(String line){
    //basic sanity
    if(null == line || line.length() < 1){
      return false;
    }


    try {
      int number = Integer.parseInt(line);

      return (number >= 0 && number <= 500);

    } catch (NumberFormatException e) {
      return false;
    }

  }


  public static void main(String[] args) {
    new ScanInfo();

  }

  public String getLineFromConsole(){
    System.out.print("\nEnter Quantity on Hand: ");
    return keyboard.nextLine();

  }

}

回答by danben

The problem is in this section:

问题出在这一节:

                        while (error==true)
                        {
                            if (Character.isLetter(input.charAt(0)))
                            {
                                System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500");
                                error=true;
                                System.out.println(qoh);
                                System.out.println(input);
                            }
                            else
                            {
                                qoh = Integer.parseInt(input);
                                error=false;
                            }
                        }

Once you have a letter in the first position, this loop can never terminate. It checks whether a letter is in the first position (it is), prints it, and repeats. Try changing to:

一旦你在第一个位置有一个字母,这个循环就永远不会终止。它检查一个字母是否在第一个位置(它是),打印它,然后重复。尝试更改为:

                            while (error==true)
                            {
                                if (Character.isLetter(input.charAt(0)))
                                {
                                    System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500");
                                    error=false;

                                    ...

Also, a couple of other things:

此外,还有一些其他的事情:

while (error == true)can be shortened to while(error).

while (error == true)可以缩短为while(error).

Also, Integer.parseIntwill throw a NumberFormatExceptionif the input is not an integer - you need to catch and handle this.

此外,如果输入不是整数,Integer.parseInt则会抛出 a NumberFormatException- 您需要捕获并处理它。

Also, why do you need the second loop at all? It seems like it is only supposed to validate the input - if so, you can move this logic into the first loop and eliminate the second one. Only use loops for things that should happen repeatedly (like the user entering input data). There is no need to check the same input repeatedly.

另外,你为什么需要第二个循环?似乎它只应该验证输入 - 如果是这样,您可以将此逻辑移到第一个循环中并消除第二个循环。只对应该重复发生的事情使用循环(比如用户输入输入数据)。无需重复检查相同的输入。