2011-10-01 4 views
2

Java를 오래 사용하지 못했습니다. 이 스크립트에서 Thread.sleep (10000); 당신은 여전히 ​​입력 할 수 있습니다 (내가 이클립스 사용) 난 정말 당신이 내가 uno.nextLine(); 10 초 대기 전 또는 후에. 도와주세요! 감사합니다간단한 Java 스캐너 문제

import java.util.Scanner; 
class Tutoiral{ 
     public static void main (String args[])throws InterruptedException { 
      Scanner uno = new Scanner(System.in); 
      Scanner uno1 = new Scanner(System.in); 
      System.out.println("What's your name?"); 
      String name = uno.nextLine(); 
      System.out.println("Hi, " + name + ". Feel free to type whatever you want :) BUT DON'T SPAM!!!!!"); 

      String typed = (": ") + uno1.nextLine(); 
      System.out.println(name + typed + " (5 types remaining)"); 
      uno.nextLine(); 
      System.out.println(name + typed + " (4 types remaining)"); 
      uno.nextLine(); 
      System.out.println(name + typed + " (3 types remaining)"); 
      uno.nextLine(); 
      System.out.println(name + typed + " (2 types remaining)"); 
      uno.nextLine(); 
      System.out.println(name + typed + " (1 type remaining)"); 
      uno.nextLine(); 
      System.out.println(name + typed + " (If you type one more time, then I'll... I'll block you! Ha!)"); 
      uno.nextLine(); 
      System.out.println(name + typed + " (tut tut tut. You have been blocked for a while for spam. Don't type EVER again ok?)"); 
      Thread.sleep(10000); 
      System.out.println("Ok, you can type again. But I wouldn't If I were you."); 

답변

2

그것이 내가 (더 uno.nextLine이 없을 때 출력을 입력 할 수 있습니다 이유를 정말 모르겠다)

nextLine에 대한 호출은 읽기 (반환) 표준 입력에서 문자를합니다. 콘솔은 사용자가 입력 한 문자 인 을 읽었는지 여부와 관계없이 인쇄합니다 ().

사용자가 사용자가 표준 입력으로 데이터를 입력하는 것을 방지 할 수 없습니다.


한 가지 해결 방법은 아마도 사용자가 입력 한 문자를 인쇄 즉 피 "지역 에코"를 사용하지 않도록하는 것입니다. 어떻게해야할지 모르겠습니다. 더러운 방법은 System.console().readPassword()입니다. 그것으로 주위 재생

, 나는 다음과 같은 슈퍼 불쾌한 해킹 해결 방법을 함께했다 (예를 들어 Thread.stop()이 좋은 이유가되지 않습니다 조심하십시오.) :

public static void turnOffLocalEcho(long ms) { 
    Thread t = new Thread() { 
     public void run() { 
      while (true) { System.console().readPassword(); } 
     } 
    }; 

    t.start(); 

    try { 
     Thread.sleep(ms); 
    } catch (InterruptedException ie) { 
    } 

    t.stop(); 
} 

단지와 Thread.sleep(10000)에 전화를 교체 이 메서드 호출의 nextSomething() 방법 중 하나를 호출 할 때 (자고, 작업, 또는 입력을 기다리는 동안) 입력을 처리 할

turnOffLocalEcho(10000); 
0

우노 때마다 입력했습니다. nextSomething()을 호출하고 입력을 구문 분석 할 필요는 없지만 사용자는이를 입력 할 수 있습니다.

0

콘솔 입력 (따라서 Scanner)은 생각하는대로 작동하지 않습니다.

콘솔 프로그램의 입력 스트림은 standard input, or stdin입니다. 이것을 프로그램의 문자 대기열로 생각할 수 있습니다.

  1. 터미널 바로 화면에 문자를 인쇄 : 당신이 콘솔 프로그램에 문자를 입력 할 때

    , 그것은 일반적으로이 효과가 있습니다.

  2. 문자가 프로그램의 표준 입력에 추가됩니다. (기술적으로 이것은 단지 당신이 줄 바꿈 (를 입력)를 입력 할 때마다 발생합니다.)

이 작업은 OS에 의해 수행, 그래서 그들은 상관없이 프로그램이 현재 표준 입력에서 데이터를 읽고 여부에 작동된다. 프로그램이 데이터를 기다리고 있으면 즉시 처리합니다 (입력 스트림 버퍼링을 무시함). 하지만 그렇지 않은 경우 (예 : 뭔가 다른 것을 처리하거나 10 초 동안 잠자기하는 경우), 프로그램이 프로그램을 읽을 때까지 문자가 대기열에 있습니다.

Scanner은 실제로 사용자에게 텍스트 줄을 요구하지 않습니다. 작동 방식 : 프로그램이 stdin을 읽으려고하면 사용 가능한 데이터가없는 경우 OS가 충분한 데이터를 제공 할 때까지 프로그램이 블로킹됩니다. Scanner.nextLine()은 개행이 읽힐 때까지 stdin에서 문자를 읽습니다.이 시점에서 마지막 개행 이후 입력 된 문자를 반환합니다. 즉, 일반적으로 Scanner.nextLine()은 사용자가 Enter 키를 누를 때까지 프로그램이 대기하도록합니다.

그러나 한 번에 두 줄 이상의 텍스트를 입력하면 터미널에 여러 줄을 붙여 넣거나 셸 파이프 또는 리디렉션 (예 : java MyProgram < file.txt)을 사용하여 프로그램은 입력을 모두 먹을 때까지 계속 실행됩니다.

프로그램이 잠자기 상태 일 때도 사용자가 입력하고 프로그램 표준에 추가 할 수 있습니다! (프로그램 끝 부분에 System.out.println(name + typed + uno.nextLine()); 사본을 추가하고 프로그램이 잠자기하는 동안 입력 할 때 어떤 일이 발생하는지 확인하십시오.)

따라서 사용자가 주 프로그램에서 읽을 내용을 입력하지 못하게하려면 주 스레드가 잠자기 상태 일 때 2 가지 작업을 수행해야합니다.

  1. 콘솔에 입력 한 문자를 반향 출력하지 않도록 콘솔에 알립니다.
  2. stdin에 공급 된 문자를 읽고 버립니다.

다른 스레드에서 System.console().readPassword()을 호출하고 출력을 삭제하여이 두 가지 작업을 수행 할 수 있습니다. 그렇게하면 10 초 후에 주 스레드가 깨어나 암호 읽기 스레드를 종료합니다. 하지만 그때까지 주 스레드가 잠자는 동안 사용자가 입력 한 내용은 이미 읽혀지고 (stdin에서 제거 된) 다른 스레드에 의해 무시되므로 실제로 사용자는 콘솔에 입력 할 수 없습니다. 이 코드는 aioobe의 답변을 참조하십시오.