Cflp

Laborator

 

Facultatea de Automatica şi Calculatoare

Departamentul de Calculatoare


 
  Lucrarea 8 Lucrarea 9 Lucrarea 10 Lucrarea 11 Lucrarea 12 Lucrarea 13 Proiect Orar


  Lucrarea 6
 

Subiecte

  

Operaţii I/E

PRINT şi READ

PRINT primeşte un singur argument pe care îl evaluează şi îl tipăreşte pe o linie nouă.

PRINT

Următorul exemplu afişează pătratele numerelor întregi pâna când îl oprim:

(defun bore-me ()
   (do ((n 0 (+ n 1)))
       (nil)
       (print (* n n))))
BORE-ME

(bore-me)
0
1
4
9
...

PRINT returnează valoarea argumentului.
Când întâlneşte (READ), interpretorul LISP se opreşte şi aşteaptă că utilizatorul să scrie o expresie. Această expresie, fară evaluare, devine valoarea lui (READ). Din cauza că READ nu afişează nimic pentru a indica faptul că aşteaptă o expresie la intrare, este o practică bună să folosim înainte PRINT pentru a semnala că se asteaptă un răspuns.

Convenţii pentru simboluri speciale

Câteodata este util să avem simboluri ce conţin caractere speciale (spaţii, paranteze etc.)
Acest lucru se realizează prin plasarea de bare verticale în jurul simbolului.

PRINT

(setq simbol1 '|(| )
|(|
(setq simbol2 '|un simbol| )
|un simbol|
(print simbol1)
|(|
|(|
(print simbol2)
|un simbol|
|un simbol|

Dacă dorim un simbol neutilizat, putem genera simboluri noi cu GENSYM.

GENSYM

(GENSYM)
G1
(GENSYM)
G2

TERPRI, PRIN1 si PRINC

TERPRI începe o linie nouă.
PRIN1 seamănă cu PRINT dar nu afisează pe o linie nouă şi nu scrie un spaţiu la sfârşit.
PRINC este asemănător cu PRIN1 dar nu va afişa nici o bară verticală dacă există.

PRIN1 şi PRINC

(print simbol2)
|un simbol|
|un simbol|
(prin1 simbol2)|un simbol|
|un simbol|

(princ simbol2)un simbol
|un simbol|

Problema 1

Scrieti o procedură PRETTY-PRINT care primeşte un argument (listă generalizată), şi îl afişează după regula:

( <element-1>
  <element-2>
  <element-3>
  ...
  <element-n> )

Orice element care este la rândul lui listă, va fi afişat în acelaşi fel recursiv.
Exemplu:

(pretty-print ' ( a (b c de) fg ))
( a
  ( b
    c
    de )
  fg )

Operaţii cu fişiere

Pentru folosirea fişierelor ca sursă sau destinaţie de informaţie, trebuie să deschidem şi să inchidem fişierele utilizate asemător ca în alte limbaje de programare.

OPEN

Deschide un fişier pentru citire sau sciere.
Sintaxa:
    (open <string nume fisier>
            [:direction [:input | :output | :io | :probe]]
            [:element-type [:string-char | :unsigned-byte | :signed-byte | ...]
            [:if-does-not-exist [:error | :create | nil | ...]])

Funcţia returnează un flux de date, folosit de restul operaţiilor de I/E.

Parametri

:direction specifică dacă fişierul este descris pentru citire (:input, implicit), pentru scriere(:output), pentru citire şi scriere (:io) sau numai pentru testarea existenţei (:probe)
:element-type specifică tipul de date cu care lucrază fişierul. Dependent de tipul ales sunt permise anumite operaţii asupra fişierului. Valoarea implicită este :string-char
:if-does-not-exist specifică reacţi în caz că fişierul pe care vrem să deschidem nu există. Poate indica semnalizarea erorii (:error), crearea automată a fişierului (:ceate) sau returnarea valori nil, fară desciderea fişierului sau semnalarea erorii.
Pentru deschiderea parametrilor suplimentari consultaţi un manual LISP.

CLOSE

Închide un fişier deschis anterior. Returnează t în caz de succes sau nil în caz de eroare.
Sintaxa:
    (close <flux fisier>)

Deschidere - citire - scriere

Următorul exemplu deschide un fişier citeşte prima expresie şi închide fişierul:

(let ((fisier         ;; variablia va memora streamul de date
     (open "fisier.txt" :direction :input))) ;; deschidere pt. citire
     (print (read fisier))                   ;; citire si afisare
     (close fisier)                          ;; eliberare de resurse
)

READ-CHAR

Sintaxa:
    (read-char [<flux fisier>
        [<semnalare eroare de sfârşit de fişier>
              [<valoare în caz de sf. de fişier>] ] ])
Citeşte un caracter din fluxul de fişier. În caz că <semnalare eroare de sfârşit de fişier> este nil, încercarea de a citi după atingera sfârşituli de fişier va rezulta returnarea valorii specificate de <valoare în caz de sf. de fişier>.

WRITE-CHAR

Sintaxa:
    (write-char <caracter> [<flux fisier> ])
Scriere caracterul dat ca parametru în fluxul specificat.

READ-LINE

Citeşte din fluxul de fişier o line şi returnează valoarea citită. Sintaxa este cea descrisă la READ-CHAR.

WRITE-LINE

Scrie în fluxul de fişier o line, primită ca parametru. Sintaxa este similară celei descrisă la WRITE-CHAR.

READ-BYTE

Citeşte din fluxul de fişier un întreg şi returnează valoarea citită. Sintaxa este cea descrisă la READ-CHAR. Fişierul trebuie să fie deschis corespunzător citirii unei octet.

WRITE-BYTE

Scrie în fluxul de fişier un întreg, primit ca parametru. Sintaxa este similară celei descrisă la WRITE-CHAR. Fişierul trebuie să fie deschis corespunzător citirii unei octet.

Funcţiile prezentate la începutul lucrării pot fi şi ele folosite cu fişiere, adăugând un flux de fişier deschis la lista de parametri actuali. Deasemenea, nefolosirea parametrului fllux la apelul funcţiilor precedente va rezulta citirea/scrierea de pe/pe intrerea/ieşirea standard.

Problema 2

Scrieţi o functie lisp, care copiează conţinutul dintr-un fişier intr-un alt fişier. Funcţia va primii ca argument numele fişierului sursă şi numele fişierului de ieşire.


Informaţii suplimanetare despre funcţii I/E pot fi găsite aici.

Probleme

Problema 1. Pretty-print.

Problema 2. Copiere de fişier.