Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reading a file in common lisp

How do i read the following file which has columns of data with header and space or tab delimited, in common lisp.

I also wanted to put the data in to list of list which contains rows.

Also how to get the difference in dates in common 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

like image 794
user458858 Avatar asked Nov 01 '10 03:11

user458858


2 Answers

The function to read a table with NUMCOLS columns from a stream

It assumes that items from the table can be read with READ. (PEEK-CHAR T ...) tests whether there is still some non-whitespace text in the stream.

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

Here are two example functions

One reads a table from a file, another one reads a table from a string.

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

Let's test it with a string:

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

Executing the test

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))
like image 92
Rainer Joswig Avatar answered Sep 28 '22 02:09

Rainer Joswig


You can read a full line from a stream with READ-LINE. You use WITH-OPEN-FILE to connect a stream to a file given that you have a filename. To get each line as an element of a list means using LOOP:

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

To split each line into columns requires some effort in basic Common Lisp, but there is this cl-utilities package which contains a function called SPLIT-SEQUENCE that can split a delimited string into a list of tokens.

First search for date-handling yielded http://common-lisp.net/project/cl-date-calc/index.html, which has a DELTA-DAYS function.

like image 27
Nietzche-jou Avatar answered Sep 28 '22 03:09

Nietzche-jou