2010-02-26 3 views
2

안녕하세요! 일부 데이터 입력 유효성 검사를 시도하지만 그것을 이해할 수 없었습니다. 입력 한 첫 번째 문자가 문자인지 확인하려고하면 무한 루프가 발생합니다. . . .Java에서 무한 루프 While

도움 주셔서 감사합니다.

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; 
       } 
      } 
     } 
    } 
+2

사이드 노트 : while (error == true) while (error) – basszero

+0

숙제가 있습니까? –

답변

3

두 번째 while 루프에는 input = keyboard.nextLine();이 없습니다.

오류가있을 때만 새 입력을 요청하도록 코드를 리팩터링 할 수 있습니다. 그래서 'ERROR ...'의 sysout 직후

추가 : 나는 실제로 이렇게 다른 것입니다. 처음에는 'error = true'가 약간 혼란 스럽습니다. 오류가 없기 때문입니다.

당신은 예를 들어, 입력을 읽고 에러가 발생했을 경우 확인을 경우는 true와 false를 돌려 tryProcessLine이라는 방법을 쓰고, 수 바로 아래 while(!tryProcessLine()){ }

작업을 예를 들어 같은보다 :

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; 
    } 
    } 
} 
+0

-1 : 이것은 무한 루프의 원인이 아닙니다. 첫 번째 루프는 첫 번째 비어 있지 않은 라인을 읽도록 고안된 반면, 두 번째 루프는이 라인이 숫자로 된 문자 만 포함하고 있다고 가정합니다 (다른 입력 라인을 읽지는 않습니다). – Adamski

+0

두 번째 루프에서 오류가 발생하면 새로운 입력을 얻으려고합니다. 그렇지 않으면 두 번째 루프가 루프가 아니어야합니다. 이제 두 번째 루프에 '오류'가 발생하면 새로운 입력이 요청되지 않고 'error == true'가 항상 true가됩니다. – Fortega

+0

제 생각에 그는 비어 있지 않은 첫 번째 행을 읽으려고합니다. 그것을 정수로 파싱하려고 시도한다. 나는 OP가 두 개의 루프를 필요로한다고 생각하지 않는다. – Adamski

1

두 번째 while 루프가 반복적으로 문자열 (input.charAt(0))의 첫 번째 문자가 문자인지 여부를 확인하기 때문에 무한 루프가 발생합니다. 이 검사의 결과가 true라고 가정하면 루프가 종료되지 않습니다.

귀하의 코드가 같은 것을 단순화 할 수

: 그것은 당신이 오류가 여전히 루프가 영원히 계속의 원인이되는 사실 = 할 문자 수있는 경우

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

, 만약 당신이 아니에요 처음으로 돌아가서 다른 줄을 읽습니다.

원하는 코드를 수행하고 구조가 조금 더 복잡합니다.

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

    } 

} 
+0

왜 입력을 정수로 두 번 파싱합니까? – Adamski

+0

"quit"! = 행이 있어야합니다! "quit".equals (line) – Fortega

+0

나는 게으르고 캡슐화가 잘못되어 정수를 두 번 구문 분석합니다. 포르타 : 당신의 변화를 만들었습니다. – Kylar

1

문제는이 섹션에 있습니다

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

첫 번째 위치에 편지가 있으면,이 루프를 종료 할 수 없다. 편지가 첫 번째 위치에 있는지 확인한 후 인쇄하고 반복합니다. 로 변경 시도 :

      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; 

            ... 

또한, 다른 몇 가지가 :

while (error == true)while(error) 단축 할 수있다.

또한 Integer.parseInt은 입력이 정수가 아니면 NumberFormatException을 던집니다.이를 잡아서 처리해야합니다.

왜 두 번째 루프가 필요합니까? 그렇다면이 논리를 첫 번째 루프로 옮기고 두 번째 루프를 제거 할 수 있습니다. 반복적으로 발생해야하는 작업 (예 : 사용자가 입력 데이터를 입력하는 경우)에만 루프를 사용하십시오. 동일한 입력을 반복해서 확인할 필요가 없습니다.