从Common Lisp中的文本文件中读取数组

时间:2012-02-02 02:20:30

标签: arrays file lisp common-lisp

我试图从文本文件中读取Lisp中的数据(实际上是一个数组)。 我尝试使用with-open-fileread-line这些东西但无法实现我的目标。我正在寻找的东西等同于在MATLAB中执行data=load('filename.txt'),因此我得到一个名为data的数组,它已将整个信息加载到filename.txt

文本文件的格式为

1.0 2.0 3.0 ...
1.5 2.5 3.5 ...
2.0 3.0 4.0 ...
 .....

尺寸也可能不同。非常感谢。

4 个答案:

答案 0 :(得分:4)

假设你的文件遵循你在问题中给出的格式模式:用白色空格分隔的一系列数字,这是一个应该做你想要的快速片段。

(defun read-array (filename)
  (with-open-file (in filename)
    (loop for num = (read in nil)
          until (null num)
          collect num)))

答案 1 :(得分:4)

执行此操作的基本方法是使用with-open-file获取输入流read-lineloop获取行split-sequence(来自库中)同名)将其拆分为字段,并parse-number(来自同名库)将字符串转换为数字。提到的所有图书馆均可从Quicklisp获得。

编辑:为了让您入门,这是一个没有验证的简单版本:

(defun load-array-from-file (filename)
  (with-open-file (in filename
                      :direction :input)
    (let* ((data-lol (loop :for line := (read-line in nil)
                           :while line
                           :collect (mapcar #'parse-number:parse-number
                                            (cl-ppcre:split "\\s+" line))))
           (rows (length data-lol))
           (columns (length (first data-lol))))
      (make-array (list rows columns)
                  :initial-contents data-lol))))

您应该添加一些检查并考虑一下如果不满足您想要获得的内容:

  • 行的长度是否相同?
  • 所有字段都是有效数字吗?

答案 2 :(得分:2)

另一种方法是利用lisp阅读器来解析文本文件中的数据。为此,我可能首先将整个文件转换为字符串,然后调用

(eval (read-from-string (format nil "~a~a~a" "(initial wrapper code " str ")")))

例如,如果您想读入一个数据文件,该数据文件是由空格/换行符分隔的所有数字,则列表中的上一个命令如下所示:

(eval (read-from-string (format nil "~a~a~a" "(list " str ")")))

答案 3 :(得分:2)

我遵循了斯万特的建议。我只需要在文本文件中使用一个列,这就是我为此目的使用的。

(defun load_data (arr column filename)
(setf lnt (first (array-dimensions arr)))
 (with-open-file (str (format nil "~A.txt" filename) :direction :input)
   (loop :for i :from 0 :to (1- lnt) :do
       (setf (aref arr i 0) (read-from-string (nth (1- column) (split-sequence:SPLIT-SEQUENCE #\Space (read-line str))))))))

谢谢大家的帮助。