Как читать ввод до EOF в Лиспе - PullRequest
8 голосов
/ 21 августа 2009

Как мне прочитать входной поток до EOF в Лиспе? В C вы можете сделать это так:

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

Я бы хотел иметь возможность передавать данные в мои программы на Лиспе без предварительного указания размера данных. Вот пример из того, что я делаю сейчас:

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

В этом цикле переменная *n* указывает количество строк, которые я передаю программе (значение читается из первой строки ввода), но я хотел бы просто обработать произвольное и неизвестное число линии, останавливающиеся при достижении конца потока.

Ответы [ 2 ]

13 голосов
/ 21 августа 2009

См. HyperSpec для READ-LINE

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

или иногда с нулем

(loop for line = (read-line stream nil nil)
      while line
      do ... )
10 голосов
/ 21 августа 2009

read-line принимает необязательный аргумент (eof-error-p), позволяющий ему возвращать либо NIL (по умолчанию), либо заданное пользователем значение (eof-value) при нажатии EOF вместо сообщения об ошибке.

С Глава 19 Успешного Лиспа :

READ-LINE & опциональный поток eof-error-p-eof-value recursive-p

В перечисленных выше функциях чтения необязательные аргументы EOF-ERROR-P и EOF-VALUE указывают, что происходит, когда ваша программа пытается выполнить чтение из исчерпанного потока. Если EOF-ERROR-P равно true (по умолчанию), то Lisp сообщит об ошибке при попытке прочитать исчерпанный поток. Если EOF-ERROR-P равно NIL, то Lisp возвращает EOF-VALUE (по умолчанию NIL) вместо сообщения об ошибке.

Вы можете использовать это как простое условие завершения для вашей функции.

...