开发者

Read Input until control+d

I want to prompt the user to begin entering characters and I want them to be able to enter characters as long as they want until they hit control+d to exit.

For example, they can type a string of numbers like: 1234567 and as soon as they decide to hit control+d the line that they entered will be displayed (so without having to hit return)

I am thinking I'll need a buffered reader or something. Any suggestion开发者_运维问答s?


What rlibby said is spot on: the CTL-D will cause the terminal to flush buffered input to the JVM. However, the keypress event itself is captured and acted on by the terminal and not passed through.

Fortunately, though, it's easy to detect. If the user hits CTL-D on a line of its own, there is no input to flush...which to the JVM is indistinguishable from EOF. Accordingly, System.in.read() will return -1 per the contract of InputStream. If you've wrapped System.in with a BufferedReader, readLine() will return null.

This is my main loop for an interactive command line tool I just wrote:

BufferedReader systemIn = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));

String line;
while((line = systemIn.readLine()) != null) {
    // my program loop.
}

One thing worth pointing out is that if the user hits CTL-D after inputting characters (but before hitting return), you'll get those characters. I don't believe there's a way to detect CTL-D when it's not on a line of its own.

DISCLAIMER: I have no idea how this applies to Windows.


http://download.oracle.com/javase/6/docs/api/java/io/BufferedInputStream.html#read%28%29

public class InputTest {
  public static void main(String[] args) throws IOException {
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    StringBuilder out = new StringBuilder();
    while (true) {
      try {
        int c = in.read();
        if (c != 4)  // ASCII 4 04 EOT (end of transmission) ctrl D, I may be wrong here
            out.append (c);
        else
            break;
      } catch (IOException e) {
        System.err.println ("Error reading input");
      }
    }
    System.out.println(out.toString());
  }
}


You are confusing the roles of your Java program and of the terminal. The terminal buffers input and occasionally supplies it to the Java program, especially after line feeds. Ctrl+D also causes the terminal to make buffered input available, or, if nothing is buffered, to terminate the input. Asking for a program to do something on Ctrl+D is essentially asking it to do something when it reads all available input (and more may become available later). Buffering input on the Java side is going to make things more complicated, rather than less.


Just adding another option for people like me who turn up 9 or so years after the question was asked. If you are using java.util.Scanner, using a String input = in.next(); will drop a NoSuchElementException when Ctrl+d is used. In this case, you can use a try-catch block to catch that particular exception and end execution of your program (either by breaking or changing your iteration value to stop the loop).

import java.util.Scanner;

while (some condition) {
  try {
    (take your input using the in.next() function here)
    ...
  } catch (java.util.NoSuchElementException e) {
    (some condition) = false;
    //OR break;
  }
}


give this code a try. it actually worked for me

    // press ctrl+Z(windows) and ctrl+D(mac, linux) for input termination
    StringBuilder out = new StringBuilder();
    String text = null;
    Scanner scanner = new Scanner( System.in );
    while( scanner.hasNextLine() )
    {
        text = new String( scanner.nextLine() );
        out.append( text );
    }
    scanner.close();
    System.out.println( out );
    System.out.println( "program terminated" );


In a GUI, you can use a KeyListener.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜