Lekcja 4 - Zróbmy sobie prostą bazę danych
Na tej lekcji dowiesz się jak zmieniać kolory w trybie tekstowym, poznasz jakie są operacje logiczne i po co one nam, oraz jak zapisać na dysk plik z tekstem i jak go później wczytać. Prowadzić to będzie do tematu tej lekcji: prostej bazy danych - ulubionego tematu znęcających się na studentach profesorów :)
Procedura TextColor
Składnia: TextColor(kolor:byte); CRT
Zmienia kolor wyświetlania tekstu, możliwe do wybrania jest 16 kolorów:
Black = 0 - czarny
Blue = 1 - niebieski
Green = 2 - zielony
Cyan = 3 - turkusowy
Red = 4 - czerwony
Magenta = 5 - karmazynowy
Brown = 6 - brązowy
LightGray = 7 - jasnoszary
DarkGray = 8 - ciemnoszary
LightBlue = 9 - jasnoniebieski
LightGreen = 10 - jasnozielony
LightCyan = 11 - jasnoturkusowy
LightRed = 12 - jasnoczerwony
LightMagenta = 13 - jasnokarmazynowy
Yellow = 14 - żółty
White = 15 - biały
Można wykonać rówież kolor migoczący, uzyskuje się poprzez dodanie do wybranego koloru liczby 128 ( Blink ) np.
Uses CRT;
Begin
TextColor(Blue);
Write('Napis Niebieski');
TextColor(8);
Write('Napis Ciemnoszary');
TextColor(Red+Blink);
Write('Napis Czerwony mrugajacy');
TextColor(15+128); { TextColor(143); }
Write('Napis Biały mrugający');
End.
Procedura TextBackGround
Składnia: TextBackGround(kolor:byte); CRT
Zmienia kolor tła wyświetlanego tekstu, możliwe do wybrania jest 8 kolorów:
Black = 0 - czarny
Blue = 1 - niebieski
Green = 2 - zielony
Cyan = 3 - turkusowy
Red = 4 - czerwony
Magenta = 5 - karmazynowy
Brown = 6 - brązowy
LightGray = 7 - jasnoszary
Przykład:
Uses CRT;
Begin
TextBackGround(Blue);
Write('Napis na niebieskim tle');
TextBackGround(4);
Write('Napis na czerwonym tle');
End.
Aby zmienić kolor podkładu dla całego ekranu należy wykonać tą procedurę i wyczyścić ekran np.
Uses CRT;
Begin
TextBackGround(Green);
ClrScr;
Write('Oto napis na całym zielonym ekranie :)');
End.
Operator AND
Mówiąc po polsku jest to operator "I" i stosuje się tam gdzie są potrzebne spełnione dwa lub więcej warunków np. w IF..THEN.. albo w pętli REPEAT..UNTIL, warunki muszą być podane w nawiasach np.
Var
a1,a2,a3:byte;
Begin
Write('Podaj 1 liczbe : ');
ReadLn(a1);
Write('Podaj 2 liczbe : ');
ReadLn(a2);
Write('Podaj 3 liczbe : ');
ReadLn(a3);
If (a1>a2) AND (a1>a3) Then WriteLn('Liczba ',a1,' jest najwieksza z podanych');
If (a2>a1) AND (a2>a3) Then WriteLn('Liczba ',a2,' jest najwieksza z podanych');
If (a3>a1) AND (a3>a2) Then WriteLn('Liczba ',a3,' jest najwieksza z podanych');
End.
Program sprawdza która z podanych trzech liczb jest największa i wyświetla ją na ekranie.
Operator OR
Mówiąc po polsku jest to operator "LUB" i stosuje się tam gdzie jest potrzebny spełniony co najmniej jeden z dwóch lub więcej warunków, stosuje się go np. w IF..THEN.. albo w pętli REPEAT..UNTIL, warunki te muszą być podane w nawiasach np.
Uses CRT;
Var
c:char;
Begin
Write('Czy na pewno ? (T/N) :');
Repeat
c:=readkey;
Until (c='t') or (c='n');
End.
Program ten czeka na wciśnięcie klawisza "t" lub "n", ale jest niedoskonały ponieważ gdy wciśniemy duży klawisz "T" lub "N" to wtedy nie zadziała. Rozwiązaniem tego jest dodanie obsługi tych klawiszy, poprawiony program wygląda więc tak:
Uses CRT;
Var
c:char;
Begin
Write('Czy na pewno ? (T/N) :');
Repeat
c:=readkey;
Until (c='t') or (c='T') or (c='n') or (c='N');
End.
Procedura Assign
Składnia: Assign(var Plik:text; nazwapliku:string);
Procedura kojarzy identyfikator "Plik" z plikiem dyskowym o nazwie "nazwapliku" w której może mieścić się jeszcze ścieżka dostępu. Bardziej jasne stanie to się przy następnych procedurach "Reset" i "Rewrite".
Procedura Close
Składnia: Close(var Plik:text);
Zamyka plik otwarty uprzednio przez "Reset", "Assign" lub "Rewrite". Zaraz zobaczysz jak to się stosuje.
Procedura Reset
Składnia: Reset(var Plik:text);
Otwiera plik "Plik" skojarzony uprzednio przez "Assign". Od tego momentu poprzez identyfikator "Plik" będzie można czytać dane poprzez Read i ReadLn z dysku np.
Var
przyklad:text; {1}
linia:string;
Begin
Assign(przyklad,'C:\AUTOEXEC.BAT'); {2}
Reset(przyklad); {3}
ReadLn(przyklad,linia); {4}
WriteLn(linia); {5}
Close(przyklad); {6}
End.
Program otwiera plik "C:\AUTOEXEC.BAT" i wyświetla z niego pierwszą linię. W kolejnych linijkach program wykonuje:
{1} Deklarujemy zmienną "przyklad" jako typ TEXT
{2} Kojarzymy zmienną "przyklad" z plikiem "C:\AUTOEXEC.BAT"
{3} Otwieramy plik "przyklad" do odczytu
{4} Wczytujemy kolejną linię ( ponieważ nie czytaliśmy z niego wcześniej czyta pierwszą ) z pliku "przyklad" i wstawiamy ją do zmiennej "linia" typu String
{5} Wyświetlamy zmienną "linia"
{6} Zamykamy plik
Funkcja EOF
Składnia: EOF(var Plik:text):boolean
Jest to funkcja zwracająca dwie wartości: prawdę (TRUE) lub fałsz (FALSE) i określa czy plik "PLIK" znajduje się w pozycji końcowej ( FALSE - są w nim jeszcze jakieś nieprzeczytane dane, TRUE - tak to koniec pliku nic więcej w nim nie ma ). np:
Var
przyklad:text;
linia:string;
Begin
Assign(przyklad,'C:\AUTOEXEC.BAT');
Reset(przyklad);
REPEAT {1}
ReadLn(przyklad,linia); {2}
WriteLn(linia); {3}
UNTIL EOF(przyklad); {4}
Close(przyklad);
End.
Program podobnie jak poprzednio otwiera plik ale odczytuje z niego wszystkie linie zaczynając od pierwszej a kończąc na ostatniej.
{1} zacznij pętlę
{2} odczytaj kolejną linię z pliku "przyklad"
{3} wyświetl ją na ekranie
{4} sprawdz czy to już koniec pliku, jeśli nie to powróć do {2} i wyświetl kolejną linię, a jeśli tak to opuść pętlę.
Procedura Rewrite
Składnia: Rewrite(var Plik:text);
Procedura ta tworzy nowy plik o nazwie skojarzonej ze zmienną "Plik" i udostępnia go do zapisu w nim danych ( poprzez Write i WriteLn ). UWAGA ! Jeżeli użyjesz tej procedury na istniejącym już pliku zostanie on usunięty i na jego miejsce utworzony nowy np.
Var
przyklad:text; {1}
Begin
Assign(przyklad,'C:\PLIKTEST.TXT'); {2}
Rewrite(przyklad); {3}
WriteLn(przyklad,'Taki sobie głupi napis zapiszemy w pliku :)'); {4}
Close(przyklad); {5}
End.
{1} definijemy zmienną "przyklad" jako typ TEXT
{2} kojarzymy zmienną "przyklad" z plikiem "C:\PLIKTEST.TXT" ale nie musi on wcale istnieć ponieważ:
{3} tworzymy plik i otwieramy go do zapisu
{4} wpisujemy do pliku linię z tekstem
{5} zamykamy plik
UWAGA ! Jeżeli nie zamkniesz pliku i opuścisz program to jakiś fragment ostatnio zapisywanych danych ulegnie skasowaniu !!!!! Czasami może się zdarzyć że plik nie został do końca zapisany więc w pierwszej kolejności sprawdź czy został on prawidłowo zamknięty !
Zaczynamy pisać prostą bazę danych
Napiszemy sobie prostą bazę osobową czyli wystarczy: imię, nazwisko i telefon. Zaczniemy pisanie krok po kroku od podstaw, tak abyś wiedział skąd i dlaczego się biorą te dziwne rzeczy, a potem z czasem będziemy ją modyfikować.
Oki zrobimy najpierw program na jedną osobę tak aby ją można wprowadzić i wyświetlić:
Uses CRT;
Var
Imie,nazwisko,telefon:string;
c,c2:char;
PROCEDURE Wprowadz;
Begin
ClrScr;
Write('Imie : ');
ReadLn(imie);
Write('Nazwisko : ');
ReadLn(nazwisko);
Write('Telefon : ');
ReadLn(telefon);
End;
PROCEDURE Wyswietl;
Begin
ClrScr;
WriteLn('Imie : ',imie);
WriteLn('Nazwisko : ',nazwisko);
WriteLn('Telefon : ',telefon);
WriteLn;
Write('Wcisnij jakis klawisz...');
c2:=readkey;
End;
Begin
Repeat
ClrScr;
Write('1. Nowy wpis 2. Wyswietlenie wpisu 3.Koniec programu : ');
Repeat
c:=readkey;
Until (c='1') OR (c='2') OR (c='3');
If c='1' Then Wprowadz;
If c='2' Then Wyswietl;
Until c='3';
End.
To już powinieneś rozumieć więc nie będę tłumaczył prosty program do wprowadzenia i wyświetlenia tylko 3 zmiennych, tylko co to za baza danych na jedną osobę ? Właśnie teraz przychodzą nam z pomocą tablice które tak wałkowałem na poprzedniej lekcji zobacz teraz jak zmienił się nasz program:
Uses CRT;
Var
Imie,nazwisko,telefon:array[1..30] of string; {1}
c,c2:char;
iloscosob:byte; {2}
t1:byte; {3}
PROCEDURE Wprowadz;
Begin
ClrScr;
Iloscosob:=iloscosob+1; {4}
Write('Imie : ');
ReadLn( imie[iloscosob] ); {5}
Write('Nazwisko : ');
ReadLn( nazwisko[iloscosob] ); {6}
Write('Telefon : ');
ReadLn( telefon[iloscosob] ); {7}
End;
PROCEDURE Wyswietl;
Begin
ClrScr;
Write('Numer wpisu ? (1..', iloscosob ,') :'); {8}
ReadLn(t1); {9}
WriteLn('Imie : ',imie[t1] ); {10}
WriteLn('Nazwisko : ',nazwisko[t1] ); {11}
WriteLn('Telefon : ',telefon[t1] ); {12}
WriteLn;
Write('Wcisnij jakis klawisz...');
c2:=readkey;
End;
Begin
Iloscosob:=0; {13}
Repeat
ClrScr;
Write('1. Nowy wpis 2. Wyswietlenie wpisu 3.Koniec programu : ');
Repeat
c:=readkey;
Until (c='1') OR (c='2') OR (c='3');
If c='1' Then Wprowadz;
If c='2' Then Wyswietl;
Until c='3';
End.
Jak widzisz linijek doszło niewiele a ilość wpisów zwiększona została do 30. Teraz opiszę co się zmieniło:
Deklaracje:
{1} zmodyfikowałem 3 zmienne z podyńczych na tablice
{2} dodałem zmienną "iloscosob" określającą ile mamy wpisów w bazie
{3} dodałem zmienną pomocniczą "t1" która będzie nam później na moment potrzebna
Główny program:
{13} wyzerowałem zmienną "iloscosob" ponieważ nie mamy jeszcze żadnego wpisu
Procedury:
{4} ponieważ procedura ma za zadanie dopisywanie nowych danych musimy zwiększyć zmienną "iloscosob" będącą równocześnie ilocią wpisów w bazie o jeden
{5} {6} {7} wprowadzenie danych do zmiennych tablicowych do elementów o numerze "iloscosob"
{8} wyświetlenie informacji o ilości dostępnych do uzyskania danych
{9} wprowadzenie zmiennej pomocniczej będącej numerem rekordu danych do wyświetlenia
{10} {11} {12} wyświetlenie danych z tablic o elementach numer "t1"
Do tamtego programu dodamy jeszcze teraz dwie procedury do zapisu i odczytu z dysku, dwie procedury w tym listingu wyciełem aby nie przeszkadzały w studiowaniu zmian w programie ale oczywiście muszą się one tam znajdować ( w listingach do ściągnięcia nie są one wykasowane ) :
Uses CRT;
Var
Imie,nazwisko,telefon:array[1..30] of string;
c,c2:char;
iloscosob:byte;
t1:byte;
plik:text; {1}
PROCEDURE Wprowadz; { taka jak poprzednio }
PROCEDURE Wyswietl; { taka jak poprzednio }
PROCEDURE Zapisz; {2}
Begin
Assign(plik,'BAZA.DAN'); {3}
ReWrite(plik); {4}
WriteLn(plik,iloscosob); {5}
t1:=0; {6}
Repeat
t1:=t1+1; {7}
WriteLn(plik,imie[t1] ); {8}
WriteLn(plik,nazwisko[t1] ); {9}
WriteLn(plik,telefon[t1] ); {10}
Until t1=iloscosob; {11}
Close(plik); {12}
End;
PROCEDURE Czytaj; {13}
Begin
Assign(plik,'BAZA.DAN'); {14}
Reset(plik); {15}
ReadLn(plik,iloscosob); {16}
t1:=0; {17}
Repeat
t1:=t1+1; {18}
ReadLn(plik,imie[t1] ); {19}
ReadLn(plik,nazwisko[t1] ); {20}
ReadLn(plik,telefon[t1] ); {21}
Until t1=iloscosob; {22}
Close(plik); {23}
End;
Begin
Iloscosob:=0;
Repeat
ClrScr;
WriteLn('1. Nowy wpis'); {24}
WriteLn('2. Wyswietlenie wpisu'); {25}
WriteLn('3. Odczyt z pliku'); {26}
WriteLn('4. Zapis do pliku'); {27}
WriteLn('5. Koniec programu'); {28}
Repeat
c:=readkey;
Until (c>='1') AND (c<='5'); {29}
If c='1' Then Wprowadz;
If c='2' Then Wyswietl;
If c='3' Then Czytaj; {30}
If c='4' Then Zapisz; {31}
Until c='5'; {32}
End.
{1} Definiujemy zmienną PLIK jako typ TEXT
{2} Tworzymy nową procedurę ZAPISZ która będzie odpowiedzialna za zapis utworzonej bazy na dysku
{3-4} Otwieramy do zapisu plik o nazwie 'BAZA.DAN'
{5} Zapisujemy ilość wpisów na dysku
{6} Zerujmy zmienną pomocniczą T1 będzie ona potrzebna do odliczania ilości zapisanych wpisów
{7} Zwiększamy zmienną T1 o jeden
{8-10} Zapisujemy IMIE NAZWISKO i TELEFON osoby numer T1
{11} Jeżeli zapisane zostało już "ILOSCOSOB" wpisów ( tzn. wszystkie ) to przejdź dalej jeśli nie wróć do {18}
{12} Zamykamy plik, gdybyśmy tego nie zrobili to stracilibyśmy część danych
{13} Tworzymy nową procedurę CZYTAJ która będzie odpowiedzialna za odczytanie bazy z dysku
{14-15} Otwieramy do odczytu plik o nazwie 'BAZA.DAN'
{16} Odczytujemy pierwszą linię będącą liczbą z informacją o ilości wpisów
{17} Zerujmy zmienną pomocniczą T1 będzie ona potrzebna do odliczania ilości odczytanych wpisów
{18} Zwiększamy zmienną T1 o jeden
{19-21} Odczytujemy IMIE NAZWISKO i TELEFON osoby numer T1
{22} Jeżeli odczytane zostało już "ILOSCOSOB" wpisów ( tzn. wszystkie ) to przejdź dalej jeśli nie wróć do {7}
{23} Zamykamy plik
{24-28} Nowe ulepszone menu :)
{29} Czekaj na wciśnięcie 1,2,3,4 lub 5
{30-31} Wywołaj nowe funkcje ( odczyt i zapis )
{32} Jeżeli wciśnięty został klawisz 5 to opuść program
I oto mamy najprostszą bazę danych, teraz możesz ją już udoskonalać, proponuję takie rzeczy:
przy wyświetlaniu danych dodać obsługę klawiszy do wyświetlania następnego/poprzedniego/pierwszego/ostatniego wpisu
opcję: nowa baza danych
możliwość zmiany nazwy zapisywanego i odczytywanego pliku
zabezpieczenie przed wyświetleniem wpisu nr. X jeżeli taki nie istnieje