Flush/Clear System.in (stdin) before reading

妖精的绣舞 提交于 2019-11-28 14:19:54

Based on @Joni's advice, i put this together:

Scanner scanner = new Scanner(System.in);
int choice = 0;
while (scanner.hasNext()){
    if (scanner.hasNextInt()){
        choice = scanner.nextInt();
        break;
    } else {
        scanner.next(); // Just discard this, not interested...
    }
}

This discards the data that is already "pending" in stdin and waits until valid data is entered. Valid, in this context, meaning a decimal integer.

This worked for me

System.in.read(new byte[System.in.available()])

There is no built-in portable way to flush the data in an input stream. If you know that the pending data ends with \n why don't you read until you find it?

A related one.

I read a double, then needed to read a string.

Below worked correctly:

double d = scanner.nextDouble();
scanner.nextLine(); // consumes \n after the above number(int,double,etc.)
String s = scanner.nextLine();

Devices usually send data using a well defined protocol which you can use to parse data segments.

If I'm right, discard data that isn't properly formatted for the protocol. This allows you to filter out the data you aren't interested in.

As I'm not familiar with the RFID scanner you're using I can't be of more help, but this is what I suggest.

You could do this with multiple threads.

  1. Your real application reads from a PipedInputStream that is connected to a PipedOutputStream
  2. You need to have one thread reading from System.in continuously. As long as the real application is not interested in the data coming from System.in (indicated by a boolean flag), this thread discards everything that it reads. But when the real application sets the flag to indicate that it is interested in the data coming from System.in, then this thread sends all the data that it reads to the PipedOutputStream.
  3. Your real application turns on the flag to indicate that it is interested in the data, and clears the flag when it is no longer interested in the data.

This way, the data from System.in is always automatically flushed/clead

The best practice (that I've found) when dealing with terminals (aka. the console) is to deal with i/o a line at a time. So the ideal thing to do is get the entire line of user input, as a string, and then parse it as you see fit. Anything else is not only implementation specific, but also prone to blocking.

Scanner sc = new Scanner(System.in);
String line = "";

while (true) {
    System.out.println("Enter something...");

    try {
        line = sc.nextLine();
        //Parse `line` string as you see fit here...
        break;
    } catch (Exception e) {}
}

I include the while & try/catch blocks so that the prompt will loop infinitely on invalid input.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!