从键盘读取并忽略已打印的文本

huangapple go评论76阅读模式
英文:

Reading from keyboard and ignoring printed text

问题

我正在编写一个Java程序(在Intellij中),该程序接受用户的命令并对命令做出反应。反应是异步的(使用单独的线程)。

Scanner in = new Scanner(System.in);
String command = null;
do {
    System.out.println("Enter command or q to exit: ");
    command = in.nextLine();
    System.out.println("Received " + command);
    obj.react(command);
} while (!command.equals("q"));

反应的对象可能需要一段时间才能完成,并在完成后打印一条消息。
问题在于,如果我开始输入一个命令,在我完成之前,对象已经打印了一些东西,那么输入的命令就会丢失。

例如,这是一个有问题的情况(斜体字是用户输入的内容):

> Enter command or q to exit: 
> 
> *go*
> 
> Received go
> 
> *goAgain*对象完成了反应!
> 
> Received 

在这种情况下,当我在打印的消息之后按回车键时,接收到的命令是空的。

是否有办法在打印了东西之后仍然保留已输入的字符?

英文:

I am writing a java program (In Intellij) that accepts a command from the user and reacts to the command. The reaction is asynchronous (using a separate thread).

    Scanner in = new Scanner(System.in);
    String command = null;
    do {
        System.out.println("Enter command or q to exit: ");
        command = in.nextLine();
        System.out.println("Received "+command);
        obj.react(command);
    }while (!command.equals("q"));

The reacting object may take a while to react and prints a message after it finishes.
The problem is that if I start typing a command, and before I finish, the object prints something, the typed command is lost.

For example Here is a problematic scenario (The text in italics is the user input):
> Enter command or q to exit:
>
> go
>
> Received go
>
> goAgainobj finished reacting!
>
> Received

In this case, when I Hit enter after the printed message, the received command is empty.

Is there any way to keep the typed characters even after something was printed?

答案1

得分: 1

如果您使用实际控制台,打印输出不会影响已输入的内容。如果您键入 'go' 并且系统打印出 'Again',那么输入缓冲区仍然知道是 'go'。这虽然不直观且难以阅读,但在中断正在运行的脚本或其他程序方面却非常实用。

这可能已经在您的集成开发环境(IDE)或系统上起作用,取决于操作系统和IDE。

如果您想要更加美观的效果,那么您需要完全控制输入和输出,就像Linux中的 'top' 命令一样(如果您了解的话)。
您可以通过使用 Console 类更好地处理这种输入方式。详情请见:https://www.codejava.net/java-se/file-io/3-ways-for-reading-input-from-the-user-in-the-console 第3条。

解决您的问题最直观的想法似乎是在您希望打印某些内容时,先读取然后移除所有输入,然后重新打印它,这样您会得到:

> go
received go
对象已完成反应!
> go
...

基本上,您总是会自己打印一个输入行,之后会首先读取并移除已经打印出来的输入。这就是为什么您需要 Console 类,因为在那里,输入和输出是同步的,因此如果您打印了某些内容,您就知道在此期间不会发生输入。

英文:

If you use an actual console, printed output will not affect written input. If you type 'go' and the system prints 'Again', then the in-buffer still knows 'go'. This is unintuitive and bad to read, but it's practical to interrupt running scripts, or other programs.

This may already work on your IDE or your system, depending on OS ans IDE.

If you want something more 'pretty' then you need to fully control input and output, much like the 'top' command in linux (if you happen to know that).
You can handle this way of input better with the Console class. See: https://www.codejava.net/java-se/file-io/3-ways-for-reading-input-from-the-user-in-the-console #3

The most intuitive idea to solve your problem seems to read, and then remove all input at the time you want to print something, and reprint it, so you'd get:

> go
received go
obj finished reacting!
> go
...

You'd basically always print an input line yourself, after first reading and removing the already printed input. This is why you need the Console class, because there, input and output are synchronized, so if you print something, you know that no input will happen in the meantime.

huangapple
  • 本文由 发表于 2020年5月4日 15:08:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/61586836.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定