Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't we read one character at a time from System.in?

Tags:

java

stdin

The program below prints each character written on standard in, but only after a new-line has been written (at least on my system!).

public class Test {
    public static void main(String[] args) throws java.io.IOException {
        int c;
        while ((c = System.in.read()) != -1)
            System.out.print((char) c);
    }
}

This prevents people from writing stuff like "Press any key to continue" and forces something like "Press enter to continue."

  • What is the underlying reason for this?
  • Is it a limitation of Java?
  • Is this behavior system-dependent (I'm on Ubuntu)? How does it work on Mac? Windows?
  • Is it dependent on the specific terminal I run the application in? (For me it behaves like this in Eclipse and in gnome-terminal)
  • Is there a workaround?
like image 844
aioobe Avatar asked Oct 24 '10 08:10

aioobe


People also ask

How do you read a single character from a scanner class?

Reading a character using the Scanner class But, you still can read a single character using this class. The next() method of the Scanner class returns the next token of the source in String format. This reads single characters (separated by delimiter) as a String.

How do you read a single character in Java?

To read a char, we use next(). next() function returns the next token/word in the input as a string and charAt(0) function returns the first character in that string.

How do you read data from system?

1.Using Buffered Reader Class This method is used by wrapping the System.in (standard input stream) in an InputStreamReader which is wrapped in a BufferedReader, we can read input from the user in the command line. The input is buffered for efficient reading. The wrapping code is hard to remember.

How does system in read work?

system. in. read() method reads a byte and returns as an integer but if you enter a no between 1 to 9 ,it will return 48+ values because in ascii code table ,ascii values of 1-9 are 48-57 .


2 Answers

What is the underlying reason for this?

Most terminals is line buffered by default, Java does not receive input until a newline.

Is it a limitation of Java?

Some ancient terminals might only have line-buffered input; though it should be possible to disable buffering in most modern terminal.

Is this behavior system-dependent (I'm on Ubuntu)? How does it work on Mac? Windows?

Yes.

Is it dependent on the specific terminal I run the application in? (For me it behaves like this in Eclipse and in gnome-terminal)

Yes.

Is there a workaround?

There are platform specific hacks. curse in Linux and Unix-like platforms, and getch() in Windows. I'm not aware of any cross-platform way.

related: Why "Press any key to continue" is bad idea:

alt text

like image 121
Lie Ryan Avatar answered Nov 15 '22 17:11

Lie Ryan


I'm on Ubuntu

Is there a workaround?

Runtime.getRuntime().exec("stty -icanon min 1").waitFor();

And after that all reads of System.in in the same process will read 1 character not waiting for EOL.

like image 33
2 revs Avatar answered Nov 15 '22 19:11

2 revs