Input 为什么在Lisp中读取文件时要运行读取行两次?

Input 为什么在Lisp中读取文件时要运行读取行两次?,input,lisp,common-lisp,Input,Lisp,Common Lisp,这是用lisp实现“cat”命令的代码,如本书第122页所述 (defun pseudo-cat (file) (with-open-file (str file :direction :input) (do ((line (read-line str nil 'eof) (read-line str nil 'eof))) ((eql line 'eof)) (format t "~A~%" line)))) (定义伪cat

这是用lisp实现“cat”命令的代码,如本书第122页所述

(defun pseudo-cat (file) (with-open-file (str file :direction :input) (do ((line (read-line str nil 'eof) (read-line str nil 'eof))) ((eql line 'eof)) (format t "~A~%" line)))) (定义伪cat(文件) (打开文件(str文件:方向:输入) (do((行)(读取str nil’eof行) (读取行str nil'eof))) ((eql行“eof)) (格式t“~A~%”行) 为什么读取行函数要运行两次?我试着只用一行读代码来运行它,但是Lisp无法完成代码

如果可以读取文件,则可以使用
(侦听文件)
进行测试

这是我的打印文件功能

(defun print-file (filename)
  "Print file on stdout."
  (with-open-file (file filename :direction :input)
          (loop
             (when (not (listen file)) (return))
             (write-line (read-line file)))))

DO变量的语法是:变量、初始化表单、更新表单。在这种情况下,初始化表单与更新表单相同。但是DO中没有这种情况的速记,因此您必须写出两次。

您需要阅读DO的语法:


第一个读取行形式是init形式,第二个是step形式。因此,在第一次迭代中,变量被设置为init表单的结果。在下一次迭代中,变量被设置为阶跃形式的值。

多个concat并使用format创建新字符串是非常浪费的。不要这样做。这是一个错误的方法,因为它会产生错误的结果。例如,如果在linux或windows中传递命名管道的名称,它可能不会立即准备好输入,因此listen将返回NIL,而函数将返回而不实际复制任何内容。