2009-11-25 2 views
10

나는 다음과 같은 코드를 사용하고 스캐너 in.hasNextInt()를 사용하여 무한 루프 :. 나는 'w'가 말해 것 "사용자가 입력 한 잘못된 입력을 입력하면, 그러나자바 :

while (invalidInput) 
{ 
    // ask the user to specify a number to update the times by 
    System.out.print("Specify an integer between 0 and 5: "); 

    if (in.hasNextInt()) 
    { 
     // get the update value 
     updateValue = in.nextInt(); 

     // check to see if it was within range 
     if (updateValue >= 0 && updateValue <= 5) 
     { 
      invalidInput = false; 
     } 
     else 
     { 
      System.out.println("You have not entered a number between 0 and 5. Try again."); 
     } 
    } else 
    { 
     System.out.println("You have entered an invalid input. Try again."); 
    } 
} 

을 다시 시도 . " "0에서 5 사이의 정수 지정 : 잘못된 입력을 입력했습니다. 다시 시도하십시오."라는 텍스트를 보여주는 무한 루프로 이동합니다.

왜 이런 일이 발생합니까? 프로그램이 명령문에 도달 할 때마다 사용자가 입력하고 Enter 키를 누를 때까지 기다리지 않아야합니까?

if (in.hasNextInt()) 
+0

'in'이 무엇인지 또는 어떻게 구성했는지 아무에게도 보여주지 않았기 때문에 어떻게 행동해야하는지 알려주지 않습니다! –

답변

13

, 당신은 스캐너에서 'w'또는 다른 잘못된 입력을 취소해야합니다. 다음과 같이, 스캐너에 next()를 호출하고 멀리 유효하지 않은 입력을 던져 반환 값을 무시하여이 작업을 수행 할 수 있습니다 :

else 
{ 
     System.out.println("You have entered an invalid input. Try again."); 
     in.next(); 
} 
2

플래그 변수가 너무 사용하기 쉽습니다. 대신 주석과 함께 명시 적 루프 제어를 사용하십시오. 또한 hasNextInt()은 차단되지 않습니다. 미래 next 호출이 차단없이 입력을받을 수 있는지 여부를 확인하는 비 차단 검사입니다. 차단하려면 nextInt() 방법을 사용하십시오. 마지막 else 블록에서

// Scanner that will read the integer 
final Scanner in = new Scanner(System.in); 
int inputInt; 
do { // Loop until we have correct input 
    System.out.print("Specify an integer between 0 and 5: "); 
    try { 
     inputInt = in.nextInt(); // Blocks for user input 
     if (inputInt >= 0 && inputInt <= 5) { 
      break; // Got valid input, stop looping 
     } else { 
      System.out.println("You have not entered a number between 0 and 5. Try again."); 
      continue; // restart loop, wrong number 
     } 
    } catch (final InputMismatchException e) { 
     System.out.println("You have entered an invalid input. Try again."); 
     in.next(); // discard non-int input 
     continue;  // restart loop, didn't get an integer input 
    } 
} while (true); 
+0

스캐너를 마지막으로 만드는 이유가 무엇입니까? – Tomek

+0

이 코드는 여전히 무한 루프를 생성합니다. – Tomek

+0

변경되지 않으므로 마지막으로 만듭니다. 컴파일러는이 때문에 특정 최적화를 수행 할 수 있습니다. 마지막 일 수있는 모든 것을 선언하는 것은 좋은 습관입니다. 사용자가 올바른 입력을 입력하면 루프가 끊어집니다. 사용자가 무한하게 선택하면 무한합니다. 원한다면 주어진 재시도 횟수 만 허용하도록 편집 할 수 있습니다. –

8

문제는 당신이 문제가 입력 과거 Scanner를 진행하지 않았다이었다. hasNextInt() 문서에서 :

반환 true, 스캐너의 입력 내의 다음의 토큰이 nextInt() 방법을 사용하여 디폴트 기수에 int 값으로 해석 할 수 있습니다. 스캐너가 입력을 지나서 진행하지 않습니다.

이 모든 hasNextXXX() 방법의 사실이다 : 그들은 Scanner를 진행하지 않고, true 또는 false을 반환합니다.

String input = "1 2 3 oops 4 5 6"; 
    Scanner sc = new Scanner(input); 
    while (sc.hasNext()) { 
     if (sc.hasNextInt()) { 
      int num = sc.nextInt(); 
      System.out.println("Got " + num); 
     } else { 
      System.out.println("int, please!"); 
      //sc.next(); // uncomment to fix! 
     } 
    } 

당신은이 프로그램이 반복적으로 int, please! 요청, 무한 루프에 들어갈 것이라는 점을 것을을 발견 할 것이다 :

여기에 문제를 설명하는 조각이다.

sc.next() 문을 주석 처리하지 않은 경우 ScannerhasNextInt()의 토큰을 통과합니다. 이 프로그램은 인쇄 할 것이다 :

Got 1 
Got 2 
Got 3 
int, please! 
Got 4 
Got 5 
Got 6 

실패한 hasNextXXX() 검사 입력을 생략하지 않는다는 사실은 의도적 인 :이 필요한 경우 해당 토큰에 대한 추가 검사를 수행 할 수 있습니다. 여기에 설명하기 위해 예입니다 :

String input = " 1 true foo 2 false bar 3 "; 
    Scanner sc = new Scanner(input); 
    while (sc.hasNext()) { 
     if (sc.hasNextInt()) { 
      System.out.println("(int) " + sc.nextInt()); 
     } else if (sc.hasNextBoolean()) { 
      System.out.println("(boolean) " + sc.nextBoolean()); 
     } else { 
      System.out.println(sc.next()); 
     } 
    } 

을이 프로그램을 실행하면 출력을 다음과 같은 것이다 : 벤 S.에 의해

(int) 1 
(boolean) true 
foo 
(int) 2 
(boolean) false 
bar 
(int) 3 
3

이 문논 블로킹 호출에 대해서는 다음과 같습니다.

또한 hasNextInt()는 차단하지 않습니다. 차후의 다음 호출이 차단없이 입력을받을 수 있는지 여부를 확인하는 비 차단 검사입니다.

... 나는 documentation가 쉽게 의견을주고 오해 될 수 있다는 것을 인식 않으며, 이름 자체가이 목적을 위해 사용되는 의미하지만. 중점 관련 인용 첨가 :

next()와 hasNext() 메소드 먼저 일치하는 모든 입력을 스킵 (예 nextInt() 및 hasNextInt()와 같은) 그 프리미티브 타입 컴패니언 방법 구분 기호 패턴을 사용하고 다음 토큰을 반환하려고 시도합니다. hasNext와 next 메소드 모두 추가 입력을 기다리는 것을 차단할 수 있습니다. hasNext 메소드 블록이 연관된 다음 메소드가 차단되는지 여부에 대한 연결이 없는지 여부.

확실한 점은 분명합니다. " hasNext 및 next 메소드"또는 "hasnext() 및 next() 둘 다"이라는 말은 동반 메서드가 다르게 작동 함을 의미합니다. 그러나 그들이 동일한 명명 규칙 (물론 문서)을 따르는 것을 볼 때, 그들은 동일하게 행동 할 것을 기대하는 것이 합리적입니다. hasNext() 은 블록 할 수 있다고 분명히 말합니다.

메타 노트 : 잘못된 게시물에 대한 댓글 일 것입니다.하지만 새로운 사용자 인 경우에만이 답변을 게시 할 수 있습니다 (또는 sytlistic 변경 사항이 아닌 위키를 편집 할 수 있음).).