praca z plikami w Turbo Pascalu rekordy

Pascal posiada kilka typów plików:

Zmienne plikowe definiuje się za pomocą typów plikowych, np.:

type plik_znk = file of char; plik_licz = file of byte; var znaki: plik_znk; liczby: plik_licz;

Tak zadeklarowane zmienne: plik_znk i plik_licz trzeba jeszcze wykonać dwie rzeczy: związać zmienne z plikami dyskowymi oraz ustawić tryb pracy.

Zwiążmy zmienne z plikami - służy do tego instrukcja ASSIGN, jej składnia wygląda tak:

assign(znaki,'znaki.dat'); assign(liczby,'liczby.dat');

I jeszcze tylko ustawmy tryb pracy i będziemy gotowi do pracy!

Są trzy tryby pracy(alfabetycznie):

Oczywiście w jednym programie, funkcji czy procedurze możemy najpierw coś dopisać, potem odczytać - trzeba tylko pamiętać o zmianie trybów, nic bowiem nie dopiszemy jeśli plik jest w trybie reset - czytania, do póki nie przejdziemy do trybu append.

Odczyt i zapis do pliku.

Realizuje się go za pomocą standardowych instrukcji read i write. Jako pierwszy argument występuje zmienna plikowa, drugim argumentem jest zmienna typu takiego jako sam plik. Czyli w naszym przykładzie plik_znk i char oraz plik_licz i integer. Np.:

read(znaki,q); { var q: char; }

read(liczby,w); { var w: interger; } write(znaki,q); {

var q: char; } write(liczby,w); { var w: interger; }

Wszelkie dokonywane zmiany w trakcie działania programu nie są dokonywane na bieżąco - dopiero wywołanie instrukcji close - powoduje zapisanie pliku na dysk.

Close(zmienna_plikowa);

Warto jeszcze przedstawić przykład kodu, który sprawdza czy plik do odczytu istnieje.

{-} repeat write('Podaj pelna nazwe

pliku do otwracia: '); readln(nazwa);

assign(zmienna_plikowa,nazwa); reset(zmienna_plikowa); if IOresult <> 0 then

writeln('Podany plik nie istnieje, wprowadz ponownie!'); until IOresult = 0; {+}

Pliki tekstowe.

Do plików tekstowych możemy wpisywać zarówno znaki jak i liczby, możemy dodawać nowe linie, kasować całe linie, dopisywać do istniejącego pliku etc. Pliki tekstowe inaczej też się deklaruje.

type plik_txt = text;

Pliki tekstowe dzielą się na wiersze, każdy z nich kończy się sekwencją EOLN - znakami: CR(powrót karetki) oraz LF(przejście do nowej linii).
Cały plik z kolei kończy się sekwencją EOF - znakami: [CTRL] [Z].

Stwórzmy więc plik tekstowy i wpiszmy do niego kilka linii tekstu.

program pliki_tekstowe; var plik: text; nazwa,linia: string[80]; { wspolrzedne X ekranu maja 80, latwiej bedzie

nam pozniej wyswietlac zawartosc pliku, jesli plik bedzie mial taka dlugosc

wierszy } begin writeln('Podaj nazwe pliku, ktory mam

utworzyc: '); readln(nazwa); assign(plik,nazwa); rewrite(plik); writeln('OK -

plik juz utworzony teraz wprowadz kilka linii tekstu'); writeln('linia

zawierajaca sama kropke - ''.'' koczy wpisywanie'); while linia <> '.' do begin readln(linia); if linia

<> '.' then writeln(plik,linia); {zauwaz, ze w

plikach nietekstowych nie mozna uzywac writeln} end;

close(plik); writeln('Dziekuje dane zostaly zapisane do

pliku: ',nazwa); readln; end.

Zawartość plików tekstowych można wyświetlać na różny sposób. Pierwszym jest odczyt znak po znaku:

program pliki_tekstowe; procedure pokaz(nazwa: string);

var plik: text; c: char; begin

assign(plik,nazwa); reset(plik); if eof(plik) then writeln('Plik ', nazwa, ' jest pusty') else begin repeat read(plik,c); write(c); until

eof(plik); end; end; var nazwa: string; begin write('Podaj nazwe pliku, ktorego zawartosc mam

wczytac: '); readln(nazwa); writeln('Zawartosc pliku ',nazwa,':'); pokaz(nazwa);

writeln('Koniec pliku.'); readln; end.

Drugim sposobem jest korzystanie wprost z funkcji readln.
Poniższy program oferuje możliwość przeglądania plików tekstowych, które mają więcej wierszy niż można wyświetlić na ekranie, zawartość pliku umieszczona jest w ramce.

program pliki_tekstowe; uses crt; var nazwa: string; i: byte; procedure

pisz(nazwa: string); var plik:

text; linia: string[77]; { uwaga inna dlugosc linii -

juz nie 80 - musze miec miejsce na ramke } i: byte; begin assign(plik,nazwa); reset(plik); { nie sprawdzam czy

dany plik istnieje - zakladam, ze tak } while not eof(plik) do begin for i:=0 to 21 do begin readln(plik,linia); { rysuje zawartosc w ramce }

writeln(chr(186):1, linia:-1, chr(186):78-length(linia)); { wychodz z pliku, nie

czekaj do i = 24, juz jest koniec } if eof(plik) then exit; end; if not

eof(plik) then begin

textcolor(lightred); write(chr(186),' >> '); write('Nacisnij enter aby

przewinac'); write(' << ',chr(186)); readln; textcolor(7); end; end; close(plik); end; begin write('Podaj nazwe pliku,

ktorego zawartosc mam wczytac: '); readln(nazwa); writeln('Zawartosc pliku

',nazwa,':'); write(chr(201)); for i:=0 to 76 do write(chr(205));

writeln(chr(187)); pisz(nazwa); write(chr(200)); for

i:=0 to 76 do write(chr(205));

writeln(chr(188)); writeln('Koniec pliku.'); readln; end.

Możemy również stworzyć własny typ pliku tekstowo-rekordowego. Jeśli rekordy będą przechowywane w pliku tekstowym, wtedy trzeba będzie każde pole zapisywać oddzielnie, rekord będzie się kończył wraz z nową linią. Krórki zarys problemu:

program pliki_tekstowe; uses ciagi; type licznik = record dzial : string[21]; autor :

string[21]; ile : longint; end; var plik: text; stats: licznik;

nazwa: string; rozmiar: integer; { rozmiar musi byc

znany i rowny rozmiarom rekordow } begin rozmiar:=21; {

ciagi autor i dzial moga miec maksymalnie 21 znakow }

assign(plik,'rekordy.txt'); rewrite(plik); with stats

do begin autor:='Lukasz

Budnik'; dzial:='Kurs programowania TP'; ile:=1222; {zapisujemy do pliku, zmienne oddziel spacja}

writeln(plik,autor:rozmiar,dzial:rozmiar,ile); { mozemy dokonac zmian }

autor:='q'; dzial:='qwq'; ile:=0; { a potem je odtworzyc oryginalne wartosci z

pliku i wyswietlic je } reset(plik); read(plik,autor,dzial,ile); { usuwamy puste

spacje z lewej, jest ich zawsze: rozmiar - length(ciag) uzywamy funkcji ltrim z

naszego modulu Ciagi } autor:=ltrim(autor); dzial:=ltrim(dzial); { tego problemu

nie ma z liczbami } writeln(autor); writeln(dzial); writeln(ile); close(plik);

end; { sekcji with } readln;

end.

Pliki znakowe.

Rozmiar plików znakowych wynosi dokładnie tyle bajtów ile jest w nim zapisanych znaków ASCII.
Poniżej prezentuję krótki program tworzący plik znaki.dat, wpisujący do niego znaki 'a'..'z', potem przepisuje całą zawartość pliku znaki.dat do pliku znaki2.dat zmieniając przy okazji wszystkie litery na ich wielkie odpowiedniki.

program pliki; type plik_znk = file of char; var znaki, znaki2:

plik_znk; i: byte; q: char; begin { przydzielmy zmienne

do konkretnych plikow } assign(znaki,'znaki.dat'); {

mozna podawac pelna sciezke } rewrite(znaki); for i:=0

to 25 do begin q:=chr(i+97); write(znaki, q); end; close(znaki); assign(znaki2,'znaki2.dat');

rewrite(znaki2); reset(znaki); { odczyt pliku znaki} while not eof(znaki) do begin read(znaki,q); { pobieram

znak - typ char } q:=upcase(q); { mala -> wlk litera } write(znaki2,q); {

zapis wlk litery do nowego pliku } end; close(znaki2); { zapisz zmiany, plik znaki zostal juz

wczesniej zapisany, teraz tylko z niego czytalem } readln; end.

Pliki liczbowe

Rozmiar plików znakowych wynosi: rozmiar bajtów typu * ilość zapisanych liczb.
Poniżej prezentuję krótki program tworzący plik liczby.dat, wpisujący do niego liczby typu longint od 1..10, potem zamknę plik i otworzę go ponownie na dopisywanie i dopiszę jeszcze 10 kolejnych liczb. Jak wiemy nie możemy skorzystać z instrukcji APPEND bo działa ona tylko na plikach tekstowych, trzeba więc zapisać poprzednią zawartość pliku i zapisać ją ponownie, tym razem powiększoną o 10 elementów.

program pliki; type plik_licz = file of longint; var liczby: plik_licz;

i: byte; z: longint; tab: ARRAY[1..10] of longint; begin { przydzielmy

zmienne do konkretnych plikow }

assign(liczby,'liczby.dat'); rewrite(liczby); randomize; z:=1000+random(10000);

{ losujemy jakas liczbe wieksza od 1 tys } for i:=1

to 10 do begin write(liczby, z); inc(z); end;

close(liczby); { zamykam plik } { otworzmy plik, zapiszmy stare liczby w

pomocniczej tablicy } reset(liczby); for i:=1 to 10 do begin read(liczby,tab [i]); end; {

zapiszmy wiec ponownie plik, najpier zapiszmy stare liczby, odtworzmy je z

tablicy } rewrite(liczby); for i:=1 to 10 do begin write(liczby, tab [i]); end; {

i dopiero teraz mozemy dopisac nowe liczby - droga przez meke, ale inaczej sie

nie da ;D } z:=random(100); for i:=1 to 10 do begin write(liczby, z); inc(z); end;

close(liczby); { zamykam plik } readln; end.

Pliki rekordowe

Tym razem już sam przykład.

program pliki; type { definicja rekordu } licznik = record dzial : string[20]; autor :

string[20]; ile : longint; end; plik_rek = file of licznik; var rekordy: plik_rek;

stats: licznik; i: byte; z: byte; q: char; begin

assign(rekordy,'rekordy.dat'); rewrite(rekordy); with

stats do begin autor:='Lukasz

Budnik'; dzial:='Kurs programowania TP'; ile:=1222; end; write(rekordy,stats); { wpisujemy caly rekord! nie

trzeba podawac kazdego pola osobno! } close(rekordy); { mozemy dokonac zmian }

stats.autor:='q'; stats.dzial:='qwq'; stats.ile:=0; { a potem je odtworzyc

oryginalne wartosci z pliku i wyswietlic je } reset(rekordy);

read(rekordy,stats); writeln(stats.autor,' ', stats.dzial,' ',stats.ile);

close(rekordy); readln; end.

Rekordy

To dane, które mogą być wieloczłonowe, np.: zrobiłeś jakąś gierkę to możesz wstawić do niej dane jako rekord, który będzie składał się z daty, ksywy zawodnika, liczby punktów, liczby zdobytych bonusów etc. Wszystko to można umieścić w jednej zmiennej. Na tej samej zasadzie pracują programy np.: w bibliotekach. Mamy: Tytuł książki, Autora, kto ją teraz ma, od kiedy ją ma etc. Przykład deklaracji rekordu dla biblioteki:

TYPE InfoBibI = RECORD { ponizej podaje pola rekordu i ich typ } Tytul,Autor:

string[1..30]; Cena: Real ; IlEgz: 0..100 ; Status:

Char END ; VAR Book : InfoBibl

;

Do pól rekordu Book możemy wpisywać wartości instrukcjami przypisania:

Book.Tytuł ;= 'Organizacja maszyn cyfrowych' ; Book.Autor :=

'Yaochan Chu'; Book.Cena ;= 150.0; Book.IlEgz := 10; Book.Status:= 'C' ;

Tablice rekordów możemy kopiować wprost:

Book2 := Book; Book3 := Book;

Proste, ale prawdziwe wtedy i tylko wtedy, gdy Book, Book2 i Book3 są tego samego typu czyli: InfoBibl.
Sprawa się troszku komplikuje(ale tylko troszkę), gdy mamy dwa różne rekordy i nazwy pól rekordów są inne(zakładam, że typy pól są takie same), wtedy trzeba ręcznie kopiować pole do pola. W poniższym przykładzie mamy dwa rekordy, są one niemal identyczne, tylko inaczej nazywają się ich pola.

TYPE Info1 = Record wiek : 0..120 ; p : char end;

Info2 = Record lata: 0..120 ; sex: char end; VAR Pierwszy : Info1 ; Drugi :

Info2; Pierwszy.wiek : = Drugi.Lata ; Drugi.sex := Pierwszy.p ;

A oto przykład.

program pokaz_rekordow; uses crt; type licznik = record dzial : string[20]; autor :

string[20]; ile : longint; end; var stats : licznik; procedure pobierz; begin

writeln('Podaj dzial, pole moze zawierac 20 liter: '); readln(stats.dzial);

writeln('Podaj autora, pole moze zawierac 20 liter: '); readln(stats.autor);

writeln('Podaj ilosc wywolan, maks. longint: '); readln(stats.ile); end; procedure pokaz; begin write('Dzial: '); writeln(stats.dzial); write('Autor:

'); writeln(stats.autor); write('Ilosc wywolan: '); writeln(stats.ile); end; begin clrscr; pobierz; pokaz;

readln; end.

Idąc za ciosem przeróbmy powyższy program na bazę danych, w tym celu utworzę tablicę rekordów:

program prosta_baza; uses crt; type licznik = record dzial : string[20]; autor :

string[20]; ile : longint; end; { wszystko globalnie } const

MAX=3; var stats : ARRAY[1..MAX] of licznik; i:

integer; procedure pobierz; begin writeln('+----------------------------+'); for i:=1 to MAX do begin writeln('REKORD nr: ',i);

writeln('Podaj dzial, pole moze zawierac 20 liter: '); readln(stats [i].dzial);

writeln('Podaj autora, pole moze zawierac 20 liter: '); readln(stats [i].autor);

writeln('Podaj ilosc wywolan, maks. longint: '); readln(stats [i].ile); writeln;

end; end; procedure pokaz; begin

writeln('+----------------------------+'); for i:=1

to MAX do begin writeln('REKORD nr: ',i); write('Dzial: ');

writeln(stats [i].dzial); write('Autor: '); writeln(stats [i].autor);

write('Ilosc wywolan: '); writeln(stats [i].ile); writeln; end; end; begin clrscr; pobierz; pokaz; readln; end.

Instrukcja wiążąca WITH

WITH jest instrukcją dzięki której oszczędzimy trochę na pisaniu w kółko nazwy rekordu. Załóżmy, że dokonujemy wpisu do zmiennej Book będącej rekordem typu BiblInfo. Najprościej jest zrobić:

book.tytul:='qwq'; book.autor:='wqq'

Czy na pewno? Za każdym razem podajemy "book" - nie że jesteśmy leniwi, ale możemy związać wczytywane zmienne z polami rekordów. Np.:

with book do

begin tytul:='qwq; autor:='wqq'; end; { dalej juz zmienne nie beda wiazane z rekordem book }

Rekordy z wariantami.

Są to tak zwane zmienne rekordowe. Rekordach z wariantami używane są jeśli piszemy uniwersalne programy, np.: operujemy na stopach i metrach jednocześnie i to od użytkownika będzie zależało czy chce posługiwać się takim a nie innym systemem jednostkowym.

type miary = record case rodzaj: (ang,pol) of ang: (stopy,cale: integer); pol: (metry,centym: integer)

end;

Teraz pokażę jak wykorzystać to w programie. Program nie jest ambitny, ale przynajmniej pokazuje możliwości i zalety wariantów.

program warianty; uses crt; type miary = record case rodzaj: (ang,pol) of ang: (stopy,cale: integer); pol: (metry,centym: integer)

end; var wymiary: miary;

wybor: char; procedure pobierz; begin if wymiary.rodzaj = pol then begin writeln('Podaj po spacji

metry i centymetry: '); with wymiary do begin readln(metry,centym); end; end else begin writeln('Podaj po spacji

stopy i cale: '); with wymiary do begin readln(stopy,cale); end; end; end; {procedury} begin clrscr;

wymiary.rodzaj:=pol; writeln('Domyslnym systemem miar jest polski system -

metrowy, wpisz ''Z'', aby zmienic'); readln(wybor); if

upcase(wybor) = 'Z' then begin

wymiary.rodzaj:=ang; { jeszcze nie wprowadzilem rekordow, nie musze nic

przeliczac } writeln('Zmieniono, teraz miary beda podawne w stopach'); end; writeln; pobierz; {tu mozesz umiescic jakies dalsze

instrukcje, to tylko przyklad} readln; end.


Wyszukiwarka

Podobne podstrony:
Budowa i opis menu edytora Turbo Pascal 7
Obsługa plików w turbo pascalu
Turbo Pascal Instrukcja przypisania
Turbo Pascal - writeln, ETI Edukacja technicyno inf,, KONSPEKTY, Konspekty
PASCAL kurs, Turbo Pascal - moduly uzytkowe, WSTĘP
PASCAL kurs, Turbo Pascal - moduly uzytkowe, WSTĘP
Budowa i opis menu edytora Turbo Pascal 7
PASCAL kurs, KURS TURBO PASCALA, KURS TURBO PASCALA - wstęp
Poradnk Turbo Pascal
Lekcja Turbo Pascala
Na czym polega programowanie w TURBO Pascalu, INFORMATYKA
Kurs języka Turbo Pascal(1)
Informatyka, TURBO PASCAL, TURBO PASCAL
Kurstpv10, Kurs Turbo Pascal 7
Turbo Pascal Zmienne i ich typy, Alicja Pary˙
Notatka txt w pascalu, Turbo pascal
Turbo Pascal - wprowadzenie, ETI Edukacja technicyno inf,, KONSPEKTY, Konspekty

więcej podobnych podstron