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 ")"))))
(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 ")"))))