变量不会在lisp循环中递增

时间:2016-07-19 16:09:26

标签: lisp conditional common-lisp conditional-statements

我正在编写一个程序来读取文件中的信息,但是当我因某种原因尝试读取信息时,我的计数变量并没有增加。

(defun fill-lib()
   (with-open-file (s-stream "/Users/David/Desktop/CS/CS_408/LISP/Books.txt"
                           :direction :input)
      (loop
        (cond((> count 1) (return "Library filled")))
          (setf (aref *lib* count)
                (make-instance 'book :title (read s-stream)
                  :author (read s-stream) 
                  :genre (read s-stream)))
          (setq count (+ count 1)))))

我有一种感觉,因为我没有正确使用循环,但我并不完全确定如何解决这个问题。

1 个答案:

答案 0 :(得分:1)

您实施循环的方式,只会将一本书添加到*lib*。这是因为当count超过1时,即在从输入文件中读取第一个书籍条目之后,您明确地终止了循环:

  (cond((> count 1) (return "Library filled")))

我想我会添加一个小函数,而不是检查一个计数器,它的唯一目的是从流中读取一个书条目,并且该函数会在没有输入时向调用者指示。 (或者,当检测到具有book-title值的nil时,您可以退出循环。最佳方法取决于输入数据的结构,以及您所追求的稳健程度,当然。)

以下是代码的粗略变体,使用添加专用于从输入中读取单个书籍条目的函数的方法:

(defstruct book 
  (title nil)
  (author nil)
  (genre nil))

(defun read-book(s)
  (make-book :title (read-line s nil :eof) 
             :author (read-line s nil :eof)
             :genre (read-line s nil :eof)))

(defun fill-lib ()
  (let ((lib ()))
    (with-open-file (s "/tmp/Books.txt" :direction :input)
      (loop for book = (read-book s)
            until (eq (book-title book) :eof) do
          (push book lib)))
    lib))

(print (fill-lib))