常见的lisp:将列表读入列表

时间:2015-10-28 17:54:28

标签: common-lisp

看起来很简单,但我无法让它发挥作用。我只需要读取一个内容只是一个大列表的文件

(a b c d)

。 。 。原样。 。 。进入我的程序列表。我有

(let ((ardplst nil))     
...
(with-open-file (in ardpfile :direction :input :if-does-not-exist nil)
    (when in
      (read-sequence ardplst in))      
        (format t "~a" ardplst))

但它不起作用。我得到了NIL。我做错了什么?

1 个答案:

答案 0 :(得分:4)

read-sequence做了什么?它从流中读取一些elements,通常是字符(但它取决于流的元素类型)并且破坏性地将它们插入到输入序列中。所以,你会收集字符#\(,然后是#\a,然后是#\Space,然后是#\b等等。然而,一旦你开始阅读就会停止到达序列的末尾:使用空列表,这意味着立即(您应该传递缓冲区,例如矢量)。在您的情况下,read-sequence返回0.

您获得nil的原因是因为您的上一个表达式是format,在上面的代码中输出到标准输出(因为t)并返回nil 。您可以使用print,它返回打印的对象。

我不明白为什么你明确地使用:if-does-not-exist nil。如果无法打开文件,您确定要静默跳过任务吗?如果您阅读的列表为空,该怎么办?如果找不到文件,您可能应该发出错误信号。

我会在禁用阅读时评估时使用read

(with-open-file (in my-file)
   (let* ((*read-eval* nil)
          (list (read in)))
     (prog1 list
       (check-type list list))))

请注意,默认:direction:input。在我看来,在这里省略这个论点并没有什么坏处,尽管有时它可以更明显地写出来。