为什么这个循环打印上一次迭代的值?

时间:2012-11-18 22:35:52

标签: loops lisp common-lisp

我有一个循环:

(defun echo-lines ()
  (loop while 
        (let ((line (read-line)))
           (if (equal line "done")
               nil
               (print line)))))

我希望它在结束行后回显用户的输入,除非他们输入“done”,在这种情况下它会停止。相反,它第一次回到空白行,之后,它回显前一个输入。 例如:

* (echo-lines)
Hello, loop.

This is my second line.
"Hello, loop." 
This is my third.
"This is my second line." 
I'm almost done.
"This is my third." 
done
"I'm almost done." 
NIL

预期:

* (echo lines)
Hello, loop.
"Hello, loop."
done
NIL

1 个答案:

答案 0 :(得分:7)

效果是由缓冲输出和PRINT的定义混合引起的。

如果底层输出流被缓冲,

PRINT不会立即写入输出。另请注意,PRINT首先打印换行符 。请注意,对于可移植代码,您应该假设输出流是缓冲的。这意味着您需要确保在需要时写入缓冲输出。使用FORCE-OUTPUT(不等待)和FINISH-OUTPUT(等待)。

这是一个稍微重写的版本。

(defun echo-lines ()
  (loop for line = (read-line)
        until (equal line "done")
        do
        (write-line line)
        (finish-output)))