tags:

views:

629

answers:

2

How do I read an input stream until EOF in Lisp?

In C, you might do it like this:

    while ((c = getchar()) != EOF)
{
 // Loop body...
}

The reason I am asking this is because I would like to be able to pipe data to my Lisp programs (I've just started learning) without having to specify the data size in advance.

Here's an example from something I'm doing now:

(dotimes (i *n*)
      (setf *t* (parse-integer (read-line) :junk-allowed T))
      (if (= (mod *t* *k*) 0) (incf *count*)))

In this loop, the variable n specifies the number of lines I'm piping to the program (the value is read from the first line of input) but I would like to just process an arbitrary and unknown number of lines, stopping when it reaches the end of the stream.

+4  A: 

read-line takes an optional argument allowing it to return NIL on hitting an EOF, instead of signalling an error. You can use this as a simple termination condition for your function. See Chapter 19 of Successful Lisp for a detailed discussion.

ire_and_curses
+5  A: 

See the HyperSpec for READ-LINE

(loop for line = (read-line stream nil :eof) ; stream, no error, :eof value
      until (eq line :eof)
      do ... )

or sometimes with nil

(loop for line = (read-line stream nil nil)
      while line
      do ... )
Rainer Joswig