在普通的lisp中读取文件

时间:2010-11-01 03:42:17

标签: file common-lisp

我如何阅读以下文件,其中包含带有标题和空格或制表符分隔的数据列,通常是lisp。

我还想将数据放入包含行的列表列表中。

另外,如何在常见的lisp

中获得日期差异

ID YR MO DA YrM MoM DaM
100 2010 2 20 2010 8 30
110 2010 4 30 2010 9 12
112 2010 8 20 2010 10 20

3 个答案:

答案 0 :(得分:10)

从流中读取包含NUMCOLS列的表的功能

它假设可以使用READ读取表格中的项目。 (PEEK-CHAR T ...)测试流中是否还有一些非空白文本。

(defun read-a-table (stream numcols)
  (cons (loop repeat numcols collect (read stream))
        (loop while (peek-char t stream nil nil)
              collect (loop repeat numcols collect (read stream)))))

以下是两个示例函数

一个从文件中读取一个表,另一个从字符串中读取一个表。

(defun read-a-table-from-file (file numcols)
  (with-open-file (stream file)
    (read-a-table stream numcols)))

(defun read-a-table-from-string (string numcols)
  (with-input-from-string (stream string)
    (read-a-table stream numcols)))

让我们用字符串测试它:

(defun test ()
  (read-a-table-from-string "ID YR MO DA YrM MoM DaM
100 2010 2 20 2010 8 30
110 2010 4 30 2010 9 12
112 2010 8 20 2010 10 20"
                            7))

执行测试

CL-USER 15 > (test)

  ((ID YR MO DA YRM MOM DAM)
   (100 2010 2 20 2010 8 30)
   (110 2010 4 30 2010 9 12)
   (112 2010 8 20 2010 10 20))

答案 1 :(得分:4)

您可以使用READ-LINE从流中读取整行。如果您有文件名,则使用WITH-OPEN-FILE将流连接到文件。将每一行作为列表的元素意味着使用LOOP:

(loop
   for line = (read-line stream nil 'eof)
   until (eq line 'eof)
   collect line)

要将每行拆分成列需要基本Common Lisp中的一些工作,但是这个cl-utilities包中包含一个名为SPLIT-SEQUENCE的函数,它可以将分隔的字符串拆分为一个标记列表。

首次搜索日期处理产生了http://common-lisp.net/project/cl-date-calc/index.html,它具有DELTA-DAYS功能。

答案 2 :(得分:1)

使用cl-ppcre。 “拆分”功能非常适用于此,我在我的程序中使用它。只需将其设置为使用#\ Space作为分隔符。