Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лаба_лисп.rtf
Скачиваний:
19
Добавлен:
21.07.2019
Размер:
3.69 Mб
Скачать

Ввод-вывод

При работе с интерпретатором Лиспа ввод-вывод выполняется ав­томатически. Интерпретатор читает вводимое пользователем s-выражение (READ), вычисляет его (EVAL) и выводит результаты (PRINT). В простей­шем случае функция READ не требует аргументов. После вызова этой функции происходит обращение к стандартному входному потоку и счи­тывание введенного пользователем s-выражения. Введенное выражение возвращается в точку вызова READ.

Определим функцию, которая находит сумму четырех введенных с клавиатуры чисел:

(defun sum4 ()

(+ (read) (read) (read) (read))

Для вызова этой функции необходимо напечатать (sum4), а затем ввести четыре числа:

> (sum4)

234

> 10

>

Если требуется вводить данные из файлов, то сначала необходимо открыть с помощью функции OPEN соответствующий входной поток:

(setf vvod (open "extern.dat" direction :input))

Для чтения выражений из открытого потока WOD необходимо со­общить его имя функции READ, т.е.

(read vvod)

В этом случае произойдет обращение к файлу "extern.dat", и из него будет считано одно s-выражение. Результатом вызова функции READ будет s-выражение, введенное из файла.

Для вывода значений в Лиспе используется функция PRINT. Эта функция имеет один аргумент, значение которого выводится в выходной поток. Функция PRINT перед выводом значения осуществляет переход на новую строку, а после печати значения выводит пробел

(print '(abc))

(a b с)

> (А В С)

Здесь список (А В С) дважды отображается на экране. Дополнительный автоматический вызов функции PRINT происходит в цикле READ-EVAL-PRINT интерпретатора.

Для вывода значений могут также использоваться функции PRIN1 и PRINC. Функция PRIN1 аналогична PRINT, но не выполняет переход на но­вую строку и не выводит пробел. Функция PRINC дает возможность напе­чатать строку без ограничивающих кавычек:

(princ "lisp") ─ > lisp

Для перехода при выводе значений на новую строку можно исполь­зовать функцию TERPRI. У функции TERPRI нет аргументов. Если требует­ся вывести на печать имя символа, содержащее пробелы, скобки или строчные и заглавные буквы, то применяют знак отмены "\" или ограничи­вающие вертикальные линии "|". Все рассмотренные функции вывода по­зволяют осуществлять вывод в выходной поток открытый, с помощью функции OPEN:

(serf stran (open "extern.dat" direction :output :if-exists :append))

(print '|a b с d| stran) ─> |a b с d|

(print '\a\C \ \d stran) ─> |aC d|

(princ '|a b с d| stran) ─ > |a b с d|

Здесь вторым аргументом функции является выходной поток STRAN, связанный с файлом EXTERN.DAT.

При работе с файлами удобно использовать макроформу WITH-OPEN-FILE. Она позволяет открыть поток, задать режим работы с ним, выполнить необходимую его обработку и закрыть его:

(with-open-file (поток имя-файла {опция}*) {декларация}* {форма}*)

Вызов WITH-OPEN-FILE базируется на использовании функции OPEN. Ре­жимы открытия потока задаются с помощью аргумента опция. Они полно­стью соответствуют ключевым параметрам, указываемым при вызове функции OPEN. Формы вызова WITH-OPEN-FILE вычисляются последова­тельно. В качестве результата возвращается значение последней формы. В приведенном ниже примере открывается поток с именем STORE, который связывается с файлом TEST1.LSP. В файл циклически записываются s-выражения, вводимые с клавиатуры. Формирование файла завершается, если с клавиатуры вводится атом EOF:

(defun writer ()

(with-open-file (store "testl .lsp" : direction :output

: if-exists : append

: if-does-not-exist :create)

(princ "Введите s-выражение")

(terpri)

(princ "Для завершения ввода напечатайте EOF")

(terpri)

(do ((item (read) (read))) ; чтение s-выражения

((eq item 'eof) 'end-of-session)

(print item store ) )))

Для управления формой вывода в Коммон Лиспе применяется функ­ция FORMAT:

(format поток шаблон &REST аргументы )

Если поток задан символом Т, то функция осуществляет вывод на экран. Шаблон представляет собой строку, которая может содержать коды для управления печатью. Перед управляющими кодами записывается знак "~" (тильда). Если в шаблоне нет управляющих кодов, то функция FORMAT выводит строку шаблона так же, как и функция PRINC.