(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
reads characters from a file. When you compute the file-length
and call read-sequence
, all you are doing is reading all characters in a flat list. Namely, lst
in your example is this list:
(#\( #\1 #\ #\2 #\ #\3 #\ #\( #\4 #\ #\5 #\ #\( #\1 #\2 #\ #\1 #\1 #\
#\9 #\ #\6 #\) #\ #\4 #\ #\8 #\ #\( #\7 #\7 #\ #\5 #\3 #\( #\4 #\7 #\)
#\) #\ #\( #\1 #\2 #\ #\1 #\5 #\ #\1 #\8 #\) #\) #\Newline)
You can see that all elements in this list are characters, they are denoted with the #\...
syntax. For example, the first item is described as follow (tested with SBCL, actual output may vary in your implementation):
* (describe (first lst))
#\(
[standard-char]
Char-code: 40
Char-name: LEFT_PARENTHESIS
; No value
(with-open-file (stream "/tmp/file-list.txt")
(read (make-concatenated-stream (make-string-input-stream "(")
stream
(make-string-input-stream ")"))))
What you want to do is to call READ
on that file:
* (with-open-file (in "/tmp/file-list.txt")
(read in))
; Evaluation aborted on #<END-OF-FILE {1013420B23}>.
And it appears also your input file misses a closing parenthesis. After fixing that, you have:
* (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)))
Here the read value is a list of numbers and nested lists.
* (describe (first *))
1
[fixnum]
; No value
---- Edit
Your flatten-list
function seems to work, what I am saying is that your input list is in another file, and that you need to extract the data using the standard Lisp reader by calling read
:
* (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)
--- Edit 2
If your file contains the list elements, like this:
1 2 3 (4 5 (12 11 9 6) 4 8 (77 53(47)) (12 15 18))
Then you could write a loop, as follows:
(loop
for form = (read in nil in)
until (eq form in)
collect form)
Or, you could use a concatenated stream:
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)))
Or equivalently:
(with-open-file (stream "/tmp/file-list.txt")
(read (make-concatenated-stream (make-string-input-stream "(")
stream
(make-string-input-stream ")"))))