apohllo.pl
więcej niż strona domowa...
 

Lekcja 25

Spis treści | Lekcja 24

25. Wejście/wyjście

W LISP istnieje szereg struktur i instrukcji służących do obsługi szeroko rozmuianego wejścia/wyjścia.

25.1 Napisy

Podstawową strukturą, która przechowuje zbiory liter jest napis. W LISP zapisujemy go przy pomocy tekstu ograniczonego podójnym cudzysłowem, np. “To jest napis”. Jest on reprezentowany jako jednowymiarowa tablica znaków o zmiennej długości. Z tego względu wszelki instrukcje nadające się dla tablic, będą działały również dla napisów. Isnieją również dedykowane istrukcje służące do manipulacji napisami. Jeśli chcemy aby napis zawierał znak podówjnego cudzysłowu lub lewego ukośnika, to musimy go poprzedzić lewym ukośnikiem np. “Cytat: \”Kości zostały rzucone \” – koniec cytatu”.

25.1.1 char

Instrukcja char pozwala na dostęp do n-tego elementu napisu. Odpowiada ona instrukcji aref, przy czym może przyjmować tylko dwa argumenty – napis oraz pozycję w napisie. Litery są indeksowane od zera. Chcą zastąpić wybrany znak innym możemy napisać

25.1

(setq napis "Ala ma kota")        =>  "Ala ma kota" 
( char napis 2)                   =>  #\a
( setf (char napis 2) #\b)        =>  #\a
napis                             =>  "Alb ma kota"

Warto zwrócić uwagę, że znaki drukują się inaczej niż napisy. Jeśli chcemy uzyskać znaki w postaci napisów, mosimy dokonać konwersji coerce ze znaku na napis.

25.1.2 format

Ważną instrukcją związana z napisami jest format. Pozwala ona wydrukwać na dowolne wyjście napisy, których elementy mogą zostać zadane jako argumenty jej wywołani. W ogólności ma ona postać (format destination string arg1 arg2 …). Destination przyjmuje najczęściej wartości nil oraz t, ale może to być dowolny strumień. Argument ten określa gdzie wynikowy łańcuch ma zostać złożony. nil oznacza, że wynikowy łańcuch ma zostać zwrócony przez instrukcję format, podczas gdy t oznacza, że wynikowy łańcuch ma zostać wydrukowany na standardowym wyjściu, a instrukcja zwraca nil.

25.2

(setq napis (fomrat nil "Ala ma kota")) 
                                  =>  "Ala ma kota" 
napis                             =>  "Ala ma kota" 
(setq napis (format t "Ala ma kota")) 
"Ala ma kota" 
                                  =>  nil
napis                             =>  nil

Jak wcześniej zauważyliśmy, w napisie mogą pojawić się elementy zadane jako argumenty insrukcji format. W napisie jednak muszą wystąpić odpowiednie znaki, które informują tą funkcję, gdzie mają się pojawić owe argumenty i jak mają zostać wydrukowane. Najczęściej stosowane zestawienia znaków, to ~D oraz ~S. Piewrszy z nich pozwala wstawić liczbę do napisu, drugi zaś inny napis bądź symbol.

25.3

(setq a 10)                       =>  10
(format t "Zmienna ~S ma wartość ~D" `a a)
Zmienna a ma wartość 10
                                  =>  nil
Innymi równie często pojawiającymi się kombinacjami znaków są ~& oraz ~%. Pierwsza z nich powoduje przejście do nowej lini, jeśli bieżąca linia nie jest pusta, podczas gdy druga, powoduje bezwarunkowe przejści do nowej linii.

25.4

(format t "Napis ~& w kilku ~& linijkach")
Napis
 w kilku
 linijkach
                                  =>  nil

25.2 Odczytywanie informacji z wejścia

Do wprowadzania informacji przez użytkownika złuży instrukcja read. Zwraca ona po prostu wartość odczytaną ze standardowego wejścia. Wartość ta nie musi być cytowan przy pomocy znaku`, ponieważ nie będzie ewaluowana.

25.5

(defun kwadrat ()
     (format t "Podaj liczbe ktorej kwadrat chcesz obliczyc: ")
     (let ((x (read)))
          (format t "~&Kwadratem liczby ~D jest ~D~%" x (* x x))
     )
  )                               =>  kwadrat
(kwadrat)
Podaj liczbę której kwadrat chcesz obliczyć: 
10
Kwadratem liczby 10 jest 100
                                  =>  nil

25.3 Operacje na plikach

Operacje na plikach najłatwiej przeprowadza się przy pomocy instrukcji with-open-file. Ma ona postać (with-open-file (var pathname) body), gdzie var to nazwa zmiennej, z którą będzie utożsamiany strumień do otwartego pliku, pathname to ścieżka dostępu do tego pliku, zaś body zawiera instukcje dokonujące operacji na otwartym pliku. Zaraz po opuszczeniu tej instrukcji, połączenie do pliku jest zamykane.

25.3.1 Odczyt z pliku

Przypuśćmy, że wpliku “dane.dat” w katalogu bieżącym znajdują sią następujące wpisy

25.6

1
(maluch polonez syrenka)

Dostęp do tych danych jest następujący

25.7

(with-open-file (plik "dane.dat")
    (let ((numer-samochodu (read plik))
          (lista-samochodow (read plik)))
         (format t "Najlepszym samochodem jest ~S~%" 
            (nth numer-samochodu lista-samochodow))
    )
)  
Najlepszym samochodem jest polonez
                                  =>  nil

25.3.2 Zapis do pliku

Jeśli chcemy zapisać jakieś informacje do pliku, to w instrukcji with-open-file dodatkowo musimy zastosować dwa słowa kluczowe :direction i :output, całą zaś forma przyjmuje postać (with-open-file (var pathname :direction :output) body). Do zapisu możemy wykorzystać wcześniej poznana instrukcję format, przy czym jej pierwszy argument powinien być nazwą otwartego pliku.

25.8

(let ((lista-samochodow '(maluch polonez syrenka))
      (numer-samochodu 2))
     (with-open-file (plik "dane.dat" :direction :output)
          (format plik "~S~%" numer-samochodu)
          (format plik "~S~%" lista-samochodow)
     )
)                                 => nil

Po wykonani tej formy w pliku “dane.dat” pojawią się następujące linie:

25.9

2
(maluch polonez syrenka)

Spis treści | Lekcja 24

lisp | Opublikowano 09:51 30-11-2010. Ostatnia modyfikacja 09:51 30-11-2010 |
comments powered by Disqus