2009-08-21 10 views
8

Jak odczytać strumień wejściowy do EOF w Lisp? W C, możesz zrobić to tak:Jak odczytać wejście do EOF w Lisp

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

Chciałbym móc danych rur do moich Lisp programów bez konieczności określania rozmiaru danych z wyprzedzeniem. Oto przykład z czegoś robię teraz:

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

W tej pętli, zmienna *n* określa liczbę wierszy Jestem orurowanie do programu (wartość jest odczytywana z pierwszej linii wejścia), ale chciałbym po prostu przetworzyć dowolną i nieznaną liczbę linii, zatrzymując się, gdy dotrze do końca strumienia.

Odpowiedz

9

read-line pobiera opcjonalny argument (eof-error-p) pozwala mu powrócić albo NIL (domyślnie) lub wartości określonej przez użytkownika (eof-value) na trafienia EOF zamiast sygnalizacji błędu.

Od Chapter 19 of Successful Lisp:

READ-LINE & opcjonalnie strumień EOF-error-p EOF-value rekurencyjne-p

W funkcji odczytu wymienionych powyżej, opcjonalne argumenty EOF-ERROR-P i EOF-VALUE określić, jakie dzieje się, gdy program próbuje odczytać z wyczerpanego strumienia. Jeśli EOF-ERROR-P ma wartość true (domyślnie), Lisp zasygnalizuje błąd podczas próby odczytania wyczerpanego strumienia. Jeśli EOF-ERROR-P jest NIL, to zamiast sygnalizować błąd, Lisp zwraca EOF-VALUE (domyślnie NIL).

Możesz użyć tego jako prostego warunku zakończenia dla swojej funkcji.

+1

@GustavBertram Nie wiem, co masz na myśli. Jest nadal dostępny do pobrania z linku, który opublikowałem ponad siedem lat temu w tej odpowiedzi. Właśnie potwierdziłem. –

13

Zobacz HyperSpec dla READ-LINE

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

lub czasami z nil

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