如何在终端上同步输入和输出?

时间:2011-03-17 23:17:53

标签: c++ c terminal stdout read-eval-print-loop

我正在为自定义脚本语言编写一个linux shell,我想在用户为单个语句输入的每个后续行之前打印一个“...”,第一行有一个“> >>“打印,然后等待输入。以下是一个例子:

>>> void f() {
...  "this is a test"
... }
>>> 

我正在阅读fgets行,在我完全阅读后,打印“...”,然后再次使用fgets调用。这适用于中等速度的交互式输入。但是如果我将包含换行符的代码粘贴到终端中,我得到的是以下内容

>>> void f() {
 "this is a test"
}
... ... >>> 

即使在我将fflush打印到stdout之后发出{{1}}电话,“...”的打印时间太晚了。有谁知道有什么特别的事要做才能使这项工作?

2 个答案:

答案 0 :(得分:1)

如果关闭终端的回声(参见stty(1) -echo),则可以完全控制何时将输入打印到屏幕上。

我的假设是粘贴会导致所有行一次写入终端,并且您的程序永远不会有机会在必要时将输出发送到终端。因此,如果您在输入时关闭echo并打印用户输入,则可以在看到换行符时执行特殊处理。

您可以看到irb程序通过在其上运行strace来执行非常类似的操作:

ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
...
ioctl(0, SNDCTL_TMR_STOP or TCSETSW, {B38400 opost isig -icanon -echo ...}) = 0

答案 1 :(得分:0)

使用stdio实际上没有一种简单的方法 - 你需要使用类似ncurses的东西来控制终端。问题在于,当您复制并粘贴多行时,它们都会在一次调用read(2)时被拉入stdin的读缓冲区,因此stdout没有机会干预并打印介入的提示。