Clisp 从文件中读取列表并将其展平,但不起作用,不将 lst 识别为列表

Clisp reading list from file and flatten it, but not working, doesnt recognize lst as a list

(defun read-file-list (infile)
  (with-open-file (instream infile :direction :input :if-does-not-exist nil)
   (when instream 
     (let ((list (make-list (file-length instream))))
       (read-sequence list instream)
       list))))


(setq lst (read-file-list "/home/Desktop/nested_list.txt"))

(flatten-list lst )

(print lst)

;(1 2 3 (4 5 (12 11 9 6) 4 8 (77 53(47)) (12 15 18)) 
; file has got this line

READ-SEQUENCE 从文件中读取字符。当您计算 file-length 并调用 read-sequence 时,您所做的只是读取平面列表中的所有字符。也就是说,lst 在你的例子中是这个列表:

(#\( # #\  # #\  # #\  #\( # #\  # #\  #\( # # #\  # # #\
 # #\  # #\) #\  # #\  # #\  #\( # # #\  # # #\( # # #\)
 #\) #\  #\( # # #\  # # #\  # # #\) #\) #\Newline)

你可以看到这个列表中的所有元素都是字符,它们用 #\... 语法表示。例如,第一项描述如下(使用 SBCL 测试,实际输出可能因您的实现而异):

* (describe (first lst))
#\(
[standard-char]

Char-code: 40
Char-name: LEFT_PARENTHESIS
; No value

(with-open-file (流“/tmp/file-list.txt”) (阅读(make-concatenated-stream(make-string-input-stream“(”) 溪流 (make-string-input-stream ")")))) 您要做的是对该文件调用 READ:

* (with-open-file (in "/tmp/file-list.txt")
    (read in))
; Evaluation aborted on #<END-OF-FILE {1013420B23}>.

而且您的输入文件似乎也缺少右括号。修复后,您有:

* (with-open-file (in "/tmp/file-list.txt")
    (read in))
(1 2 3 (4 5 (12 11 9 6) 4 8 (77 53 (47)) (12 15 18)))

这里读取的值是一个数字列表和嵌套列表。

* (describe (first *))
1
[fixnum]
; No value

---- 编辑

您的 flatten-list 函数似乎有效,我的意思是您的输入列表在另一个文件中,您需要通过调用 reader 使用标准 Lisp reader 提取数据=27=]:

* (with-open-file (in "/tmp/file-list.txt")
    (flatten-list (read in)))

(1 2 3 4 5 12 11 9 6 4 8 77 53 47 12 15 18)

--- 编辑 2

如果您的文件包含列表元素,如下所示:

1 2 3 (4 5 (12 11 9 6) 4 8 (77 53(47)) (12 15 18))

然后你可以写一个循环,如下:

(loop 
  for form = (read in nil in)
  until (eq form in)
  collect form)

或者,您可以使用串联流:

USER> (with-input-from-string (open "(")
        (with-input-from-string (close ")")
          (with-open-file (file "/tmp/file-list.txt")
            (read (make-concatenated-stream open file close)))))
(1 2 3 (4 5 (12 11 9 6) 4 8 (77 53 (47)) (12 15 18)))

或等价地:

(with-open-file (stream "/tmp/file-list.txt")
  (read (make-concatenated-stream (make-string-input-stream "(")
                                  stream
                                  (make-string-input-stream ")"))))