Чтение и запись информации в файлы
ЛЕКЦИЯ 10.
Чтение и запись информации в файлы
Содержание
10.1 Задание параметров при определении функций.
При определении функции можно использовать механизм ключевых слов для того чтобы при вызове функций аргументы трактовать по разному.
С помощью ключевых слов в лямбда-списке можно выделить
Ключевые слова начинаются с символа & и их записывают перед соответствующими параметрами в лямбда-списке.
Действие ключевого слова распростроняется до следующего ключевого слова.
Параметры, перечисленные в лямбда-списке до первого ключевого слова, являются обязательными.
10.1.1 Необязательные параметры &optional
Вы можете определить необязательные аргументы для вашей функции. Любой аргумент после символа &optional необязательный:
* ( Defun bar ( x &optional y) ( if y x 0 )) bar * ( Defun baaz ( &optional ( x 3 ) ( z 10 )) ( + x z) ) BAAZ * ( bar 5 ) 0 * ( bar 5 t) 5 * ( Baaz 5 ) 15 * ( Baaz 5 6 ) 11 * (Baaz) 13
Можно вызывать функцию bar или с одним или с двумя аргументами. Если она вызвана с одним аргументом, x будет связано со значением этого аргумента и незаданный аргумент y будет связан с nil; если она вызвана с двумя аргументами,x и y будут свя- заны со значениями первого и второго аргумента, соответственно.
Функция baaz имеет два необязательных аргумента. Кроме этого она определяет недостающие знaчения для каждого из них: если пользователь определит только один аргумент, z будет связано с 10 вместо nil, и если пользователь не определит никаких аргументов, x будет связана с 3 и z с 10.
Такое определение значений называется определение по умолчанию.
10.1.2 Переменное количество аргументов &rest
Вы можете задавать вашу функцию принимающей любое число аргументов, заканчивая список аргументов &rest параметром.
LISP будет собирать все аргументы не попавшие в обязательные параметры в список и связывать &rest параметр с этем списком.
Итак:
* ( Defun foo ( x &rest y) y)
FOO
* ( Foo 3 )
NIL
* ( Foo 4 5 6 )
(5 6)
* ( defun fn ( x &optional y &rest z)) (list x y z)) fn
* (fn 'a)
(A NIL NIL)
* ( a b (c d))
10.1.3 Ключевые параметры Можно задать функции другой вид необязательного аргумента называемого аргументом ключевого слова. Пользователь может задавать эти аргументы в последующем в любом порядке, потому что они маркированы ключевыми словами. Символы t и nil называются константами-символами, потому-что они при выполнении дают сами себя.
Существует целый класс таких символов, которые называются ключевыми словами; любой символ, чье имя начинается с двоеточия является ключевым словом.
(Ниже приведены некоторые использования ключевых слов).
Примеры:
* :this-is-a-keyword
:THIS-IS-A-KEYWORD
* :so-is-this :SO-IS-THIS
* :me-too :ME-TOO
( Defun foo ( &key x y) ( cons x y) )
FOO
* ( Foo :x 5 :y 3 )
(5 . 3)
* ( Foo :y 3 :x 5 )
(5 . 3)
* ( Foo :y 3 )
( NIL. 3 )
* (Foo)
(NIL)
&key параметр может иметь также значение по умолчанию:
* ( Defun foo ( &key ( x 5 )) x )
FOO
* ( Foo :x 7 )
7
* (Foo)
5
(defun test ( x &optional (y 3) (z 4) &rest a) (cons z ( list x a y)))
(test 1 2 3)
(test 1)
(test 3 4 5)
(test 3 2 1 1 2 3)
10.2 Входные и выходные потоки. При вводе и выводе информации в Лиспе используется понятие потоков - stream
Для потока определены ИМЯ , операции открытия open операции закрытия clouse направления output и input
10.3 Определение выходных и входных потоков.
Для открытия файла для записи задается его имя, производится операция open и указывается направление output:
(setq our-output-stream (open "sesame" :direction :output))
Зададим
(setq s 'e)
Можно вывести это значение в файл
(princ s our-output-stream) ;
Можно занести список
(print '(a b c d) our-output-stream)
Чтобы правильно закрыть поток необходимо в конец поместить
(terpri our-output-stream)
Затем файл закрывается
(close our-output-stream)
Можно посмотреть информацию в файле.
Откроем файл для чтения:
(setq our-input-stream (open "sesame" :direction :input))
Прочитае информацию
(read our-input-stream)
Закроем файл
(close our-input-stream)
10. 4 Чтение символов из файла
Предположим, что в файле хранится символьная информация, необходимая нам для обработки. Причем нас интересует каждый символ в файле. До сих пор мы могли вводить только атомы, числа и списки.
Сформируем файл
Пусть
(setq s "---+++")
(setq p "+++---")
Определим поток вывода
(setq our-output-stream (open "picture.spl" :direction :output)) (princ s our-output-stream) ; записываем первую стороку (terpri our-output-stream) ; заканчиваем ее (princ p our-output-stream) ; записываем вторую строку (terpri our-output-stream) ; заканчиваем файл
Тепрь файл закрывается
(close our-output-stream)
В файле теперь находится
---+++ +++---
Для чтения символов из файла будем использовать функцию
(READ-CHAR )
Данная функция позволяет читать печатные символы ( CHAR) из файла. В качестве значения получается десятичное представление кода символа.
Используе эту функцию для посимвольного ввода информации из файла для ее последующего анализа
Определим
(setq our-input-stream (open "picture.spl" :direction :input))
Для чтения символа используем
(read-char our-input-stream)
Будем получать последовательность значений
43 43 43 45 45 45 10 и т.д.
Для восстановления содежимого файла применяется перекодировка
(setq x (read-char our-input-stream)
То содержимое x можно показать
(cond (( = x 43) (prin1'+)) (( = x 45) (prin1 '-)) (( = x 10 ) (terpri)))
Можно представить информацию без искажений, если использовать цикл
(loop (progn (setq x (read-char our-input-stream) ) (cond (( = x 43) (prin1'+)) (( = x 45) (prin1 '-)) (( = x 10 ) (terpri))))))
После вывода имеем
---+++ +++---
Закрытие входного потока
(close our-input-stream)
Для поиска конца файла можно анализировать ошибку чтения, но лучше знать длину файла до начала работы с ним.