Робота з файлами у Common Lisp

ред.

По замовченню за пристрій потокового вводу (CIS - Current Input Stream) береться консоль.

  1. Для читання даних з вхідного потоку використовують функцію READ. Після виконання команди (SETQ a (READ)) ви повинні ввести з консолі вираз, який буде прочитано та присвоєно змінній а. При цьому якщо буде введено декілька об’єктів, то змінній а буде присвоєно перший об’єкт. Наприклад, якщо ви введете: as bf gh, то змінна a прийме значення as. Якщо Ви хочете ввести список (складний об’єкт), то його необхідно вводити в круглих дужках: (as df gh).
  2. Функція (CLEAR-INPUT) чистить буфер вводу. В будь-якому випадку повертається NIL.
  3. Функція (READ-LINE) читає елементи з CIS поки не буде прочитано символ переходу на новий рядок (<return>). Повертається символ, Р-ім’я якого складається з усіх прочитаних символів як ті були розташовані у вхідному рядку, окрім <return>.
  4. Функція (READ-CHAR) читає наступний елемент з CIS та повертає його.
  5. Функція (UNREAD-CHAR) повертає в CIS останній прочитаний символ.
  6. Функція (LISTEN) повертає T якщо CIS не порожній, та NIL якщо ми дійшли до кінця файлу.
  7. Функції (OPEN-INPUT-FILE “<name>”) та (CLOSE-INPUT-FILE “<name>”) використовуються для відкриття та закриття файла <name> для вводу.
  8. Функції (OPEN-OUTPUT-FILE “<name>”) та (CLOSE-OUTPUT-FILE “<name>”) відповідно відкривають та закривають файл <name> для виводу інформації.

Приклади

ред.

1. Надрукувати кількість літер sym в файлі name.

(DEFUN f (name sym) (SETQ a (READ))

(SETQ c 0) (IF (EQL a sym) (INCQ c)) )

(OPEN-INPUT-FILE name) (CLOSE-INPUT-FILE name)

(LOOP c )

((NOT (LISTEN)))


2. Надрукувати файл в оберненому порядку, якщо його елементи є атомами.

(DEFUN rew (in out) (PUSH (READ) temp) )

(OPEN-INPUT-FILE in) (LOOP

(OPEN-OUTPUT-FILE out) ((EQL temp NIL))

(SETQ temp NIL) (WRITE (POP temp))

(LOOP (SPACES 1) )

((NOT (LISTEN))) (CLOSE-INPUT-FILE in)

(CLOSE-OUTPUT-FILE out) )


Завдання

ред.

1. Написати функцію (SRT <in> <out>), яка сортує текстовий файл <in> та виводить дані в файл <out>.

2. Написати функції (PRNUM2 num) та (PRNUM16 num), які відповідно друкують введені десяткові числа в двійковому та шістнадцятковому представленні.

3. Згенерувати за даними числом n та символом y список (y yy yyy yyyy .... yyyyyyyy. Кількість літер s в останньому елементі списку дорівнює n.

Відповіді

ред.

1. (DEFUN appl (lst1 lst2)

((NULL lst1) (append lst3 lst2))

((NULL lst2) (append lst3 lst1))

((STRING< (CAR lst1) (CAR lst2)) (CONS (CAR lst1) (appl (CDR lst1) lst2)))

(CONS (CAR lst2) (APPL lst1 (CDR lst2))) )


(DEFUN QSORT (lst)

((NULL (CDR lst)) lst)

((NULL (CDDR lst))

((STRING< (CAR lst) (CADR lst)) lst)

(CONS (CADR lst) (CONS (CAR lst) NIL)))

(SETQ tmp1 (SPLIT lst))

(APPL (QSORT tmp1) (QSORT lst)) )


(DEFUN srt (in out)

(OPEN-INPUT-FILE in)

(OPEN-OUTPUT-FILE out)

(SETQ temp NIL)

(LOOP

((NOT (LISTEN)))

(PUSH (READ) temp) )

(setq temp1 (qsort temp))

(print temp1)

(CLOSE-INPUT-FILE in)

(CLOSE-OUTPUT-FILE out) )


2. (DEFUN prnum2 (num)

(SETQ res NIL)

(LOOP

((= num 1))

(SETQ tmp (DIVIDE num 2))

(SETQ num (CAR tmp))

(PUSH (CDR tmp) res) )

(PUSH 1 res)

(PACK res) )


(DEFUN prnum16 (num)

(SETQ res NIL)

(LOOP

((< num 16))

(SETQ tmp (DIVIDE num 16))

(SETQ num (CAR tmp) tmp (CDR tmp))

(IF (>= tmp 10) (SETQ tmp (ASCII (+ (- 65 10) tmp))))

(PUSH tmp res) )

(IF (>= num 10) (SETQ num (ASCII (+ (- 65 10) num))))

(PUSH num res)

(PACK res) )


3. ; (m1 y 7 y) -> (y yy yyy yyyy yyyyy yyyyyy yyyyyyy)

(DEFUN m1 (sym n list)

((ZEROP n) NIL)

(CONS (APPEND sym list) (m1 sym (- n 1) (PACK* sym list))) )