How to read input until EOF in Lisp

common-lisp, eof, lisp

Solution

`read-line` takes an optional argument (`eof-error-p`) allowing it to return either `NIL` (default) or a user-specified value (`eof-value`) on hitting an `EOF`, instead of signalling an error.

From Chapter 19 of Successful Lisp:

READ-LINE &optional stream eof-error-p eof-value recursive-p

In the read functions listed above, optional arguments `EOF-ERROR-P` and `EOF-VALUE` specify what happens when your program makes an attempt to read from an exhausted stream. If `EOF-ERROR-P` is true (the default), then Lisp will signal an error upon an attempt to read an exhausted stream. If `EOF-ERROR-P` is NIL, then Lisp returns `EOF-VALUE` (default `NIL`) instead of signalling an error.

You can use this as a simple termination condition for your function.

Problem

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... } ``` I would like to be able to pipe data to my Lisp programs 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.

Original source