Prednka 6 sbory l kontanty l Sbory l
Prednáška 6 súbory l konštanty l
Súbory l údaje uložené v poli (listboxe) je niekedy žiaduce uložiť – kvôli zrýchleniu ladenia – kvôli uchovaniu dôležitých hodnôt l vezmime najprv pole l Uložte do súboru ‘moje data’ čísla, ktoré máte uložené v poli. l na to, aby sme údaje mohli ukladať, potrebujeme v prvom rade určiť typ súboru, do ktorého budeme zapisovať – v pascale sa typ súboru často odvíja od typu údajov, ktoré doň ukladáme – možno ho definovať ako typ alebo ho postačí len deklarovať type TSubor=file of integer; var subor: file of integer;
Kód pre počet 10 var pole: array[1. . 10] of integer; subor: file of integer; i: integer; begin for i: =1 to 10 do pole[i]: =random(1000); // pripravi premennu subor tak, aby ukazovala na udaje // v subore mojedata assignfile(subor, 'mojedata'); // vytvori (ak existuje vymaze) subor a pripravi ho na zapis // pokial nie je zadana cesta vytvori ho v aktualnom adresari rewrite(subor); for i: =1 to 10 do // vypise (zapise) udaje na miesto, kam ukazuje premenna subor // u nas ukazuje na subor mojedata, takze sa zapisuje tam write(subor, pole[i]); // ukonci subor, potvrdi zapis a zatvori subor closefile(subor); end;
Načítanie údajov zo súboru predstavuje opačný prístup k údajom l hypoteticky tu však existuje malý zádrheľ: l – môže sa stať, že programátor bude chcieť otvoriť údaje zo súboru iného – – programátora, ktorého počet prvkov nie je totožný s tým jeho zásah do programu je pomerne jednoduchý, no vyžaduje prepísanie hodnoty na viacerých miestach určité riešenie poskytuje použitie premennej pocet, ktorou by sme kód pri zápise i pri čítaní mohli nahradiť nerieši sa tým však deklarácia (definícia) poľa, ktorá nemôže ako ohraničenia používať hodnoty premenných (nie sú v dobe vyhradzovania pamäte pre pole známe) problém sa rieši používaním konštánt (kľúčové slovo const)
Konštanty l sú počas behu programu nemenné l zmenou hodnoty sa menia na všetkých miestach naraz l môžu byť deklarované v príslušnej procedúre, obvykle sa však umiestňujú pre klauzulu Type na začiatku súboru
Kód s využitím konštanty procedure TForm 1. Button 2 Click(Sender: TObject); const pocet=10; var pole: array[1. . pocet] of integer; subor: file of integer; i: integer; begin // opat pripravi premennu tak, aby ukazovala na udaje // v subore mojedata assignfile(subor, 'mojedata'); // otvori subor na citanie reset(subor); for i: =1 to pocet do // precita zo suboru udaj a posunie citajuci // ukazovatel o poziciu dalej read(subor, pole[i]); // zatvori subor closefile(subor); end;
Praktickejšie riešenie l nie vždy je potrebné využívať všetky vyhradené položky poľa – niekedy ich „pre istotu“ vyhradíme viac ako spotrebujeme a nemusíme ich ani zďaleka uložiť všetky (napr. neukladáme nulové položky a pod. ) – pokiaľ by sme zo súboru načítavali viac hodnôt ako je v ňom uložených - skolabuje – ukazovateľ na súbor nás v každom momente dokáže informovať o tom, či sme už prečítali všetky údaje – stačí sa len vhodne opýtať
Kód procedure TForm 1. Button 3 Click(Sender: TObject); var pole: array[1. . pocet] of integer; subor: file of integer; i: integer; begin assignfile(subor, 'mojedata'); // otvori subor na citanie reset(subor); i: =0; // index pola, do ktoreho sa nacitava // kym nie je koniec (End Of File) suboru while not EOF(subor) do begin inc(i); // index sa posunie // mozno ho pouzit aj na zistenie poctu ulozenych zaznamov read(subor, pole[i]); // udaj sa precita do pola end; Show. Message(‘Nacital si ’+Int. To. Str(i)+’ poloziek. ’) closefile(subor); end;
Údaje v súbore of integer l pokiaľ sa pozrieme do súboru obsahujúceho uložené pole čísel, uvidíme len akési nezmyslené znaky, ktoré pre nás nič nevyjadrujú avšak systém ich z nejakého dôvodu načíta ako čísla, ktoré sme zadávali l ak údaje zobrazíme hexadecimálne, vidíme, že súbor obsahuje 10 „štvorbajtíc“, t. j. pre každé zapísané číslo práve 4 bajty, ktorými je reprezentovaný typ integer. – Pokiaľ by sme údaje chceli zrekonštruovať, prostredníctvom prevodu zo 16 -kovej do desiatkovej sústavy by sme nemali mať problém. . .
Údaje v súbore of integer II. l výhodou takéhoto zápisu je rýchle a jednoduché ukladanie numerických hodnôt aj ich načítavanie priamo do celočíselného poľa l nevýhodou je nemožnosť (sťaženie) zásahu do údajov v súbore – o čo krajšie by bolo, keby sme údaje videli a mohli prepísať aj manuálne v nejakom textovom súbore –. . . o to pomalšie bude samozrejme ukladanie i načítavanie, pretože budeme potrebovať údaje konvertovať z číselných na textové. . .
Textový súbor l ako najprijateľnejšie riešenie na ukladanie textových informácií sa javí file of string – pokiaľ však takýto typ súboru definujeme (deklarujeme), kompilátor nás ďalej nepustí – typ nie je použiteľný ako typ súboru l l problémom je variabilná (nie pevná) dĺžka (a tým aj kapacita použitej pamäte) premenné typu string prvým riešením je určiť presný počet znakov, ktoré sa majú pre jednu položku v súbore vyhradiť, napr. : file of string[50] – tým sa zabezpečí ukladanie 50 znakových hodnôt bez ohľadu na to, či budú naplnené alebo nie
Textový súbor II. tento spôsob však príliš plytvá miestom l alternatívou je použiť súbor typu text l – zápis: l l var subor: text teda nie file of text – potreba deklarovať subor v časti public alebo private (nepostačí ho použiť v deklaračnej časti procedúry) prípadne definovať najprv vlastný typ v sekcii type (potom ho možno použiť i v deklarácii procedúry) l tento typ nepodporuje mnohé funkcie „typových“ súborov, no pre naše ďalšie potreby je optimálny
Príklad l Uložte údaje z poľa do textového súboru „data. txt“ tak, aby boli zrozumiteľné aj po otvorení v textovom editore. procedure TForm 1. Button 1 Click(Sender: TObject); const pocet=20; var i: integer; pole: array[1. . pocet] of integer; begin for i: =1 to pocet do pole[i]: =-50+random(101); // generuje nahodne hodnoty -50 -50 // subor je deklarovany v casti private ako text assignfile(subor, 'data. txt'); rewrite(subor); for i: =1 to pocet do write(subor, Int. To. Str(pole[i])); closefile(subor); end;
Príklad II. l výsledok je síce na prvý pohľad zrozumiteľný no na pohľad druhý ním príliš nadšení asi nebudeme niekedy je totiž problematické posúdiť kde jedno číslo končí a druhé začína l vkladajme nové číslo vždy do nového riadku: l assignfile(subor, 'data. txt'); rewrite(subor); for i: =1 to pocet do writeln(subor, Int. To. Str(pole[i])); closefile(subor); l ln zabezpečí po zápise automatické „odriadkovanie“
Príklad III. l Uložené údaje načítajte do poľa. var pocet: integer; pole: array[1. . 20] of integer; riadok: string; begin pocet: =0; assignfile(subor, 'data. txt'); reset(subor); while not EOF(subor) do begin // do premennej riadok precita text z aktualneho riadku readln(subor, riadok); inc(pocet); // zvysi pocet // riadok skonvertuje na cislo a vlozi do pola // priamo vlozit nie je mozne, pretoze treba robit konverziu // a parametrom readln musi byt premenna nie konverzna funkcia pole[pocet]: =Str. To. Int(riadok); end; closefile(subor); end;
Ukladanie a čítanie listboxu l úplná analógia, uvádzame len kód – zápis: assignfile(subor, 'data. txt'); rewrite(subor); for i: =0 to Listbox 1. Items. Count-1 do writeln(subor, Listbox 1. Items. Strings[i]); closefile(subor); – čítanie: Listbox 1. Items. Clear; assignfile(subor, 'data. txt'); reset(subor); while not EOF(subor) do begin readln(subor, riadok); Listbox 1. Items. Add(riadok); end; closefile(subor);
Určenie názvu súboru za behu l ukladanie doposiaľ do pevne stanoveného súboru – prax: výber súboru v dialógu – riešenie: použitie systémových dialógov Save. Dialog l Open. Dialog l
Dialógy l Uložiť – relatívne zložitejšia operácia, ktorú však rieši používanie dialógov (v systéme preddefinovaný formulár umožňujúci nastavenie základných parametrov systému) – pre ukladanie: Save. Dialog – výsledkom je získanie zadaného názvu súboru
Parametre Save. Dialogu l Deault. Ext – koncovka, ktorá sa auto- maticky pridá súboru pri uložení – v prípade nepoužitia: ručné zadávanie koncovky l súbor bez koncovky => ochudobnenie o ikonu a automatické otvorenie po dvojkliku l
Parametre II. l Filter – určuje zoznam typov súborov v dialógovom okne – prvý stĺpec obsahuje text, ktorý bude v okne zobrazený, druhý masku súborov, ktoré sa budú zobrazovať l Title – text zobrazovaný v hlavičke ukladacieho dialógu
Použitie dialógu v aplikácii l Dialogs (Save, Open. . . ) – nevizuálne komponenty, t. j. po spustení aplikácie ich nevidieť, no možno ich v kóde používať – nepíšeme kód do udalosti zobrazenej po dvojkliku – častá chyba v nižších verziách!!! – potrebné volanie, ktoré zobrazí okno, umožní zadanie názvu a po zatvorení ho vráti
Uloženie procedure TForm 1. Button 1 Click(Sender: TObject); var nazov: string; i: integer; begin // ak sa savedialog ukonci potvrdenim (kliknutim na ulozit), prebehne // vetva podmienky – ak sa zrusi, nic sa neudeje // execute - funkcia, ktora vrati hodnotu true pre potvrdenie a false pre zrusenie if savedialog 1. execute then begin // do premennej precitame nazov suboru zadany v Save. Dialogu // uložená je kompletná cesta k súboru nazov: =Save. Dialog 1. File. Name; // nasleduje už známe ukladanie assignfile(subor, nazov); rewrite(subor); for i: =0 to Listbox 1. Items. Count-1 do writeln(subor, Listbox 1. Items. Strings[i]); closefile(subor); end;
Otvorenie l analógia s uložením – použije sa Open. Dialog – možno nastaviť Title a Filter l ako prednastavený sa berie typ súboru zadaný vo filtri ako prvý begin if opendialog 1. execute then begin nazov: =Open. Dialog 1. File. Name; Listbox 1. Items. Clear; assignfile(subor, nazov); reset(subor); while not EOF(subor) do begin readln(subor, riadok); Listbox 1. Items. Add(riadok); end; closefile(subor); end;
Existencia súboru l niekedy môže byť užitočné zistiť, či sa daný súbor už v zadanej lokalite nenachádza: – if File. Exists(nazov) then l napr. kvôli tomu, aby sa mohol vymazať: – Delete. File(nazov);
Reprezentácia údajových typov aby sme vedeli, koľko miesta na disku zaberú l integer: l Typ Integer Cardinal Rozsah -2147483648. . 2147483647 0. . 4294967295 veľkosť znamienkový 32 -bitový (4 bajty) bez znamienka 32 -bitový Typ Shortint Smallint Longint Int 64 Byte Word Longword Rozsah -128. . 127 -32768. . 32767 -2147483648. . 2147483647 -2^63. . 2^63 -1 0. . 255 0. . 65535 0. . 4294967295 veľkosť signed 8 -bit signed 16 -bit signed 32 -bit signed 64 -bit unsigned 8 -bit unsigned 16 -bit unsigned 32 -bit l Integer pozostáva zo 4 bajtov, z ktorých 1 bit je vyhradený pre znamienko – – do jedného bytu možno zakódovať 256 rôznych hodnôt do dvoch bajtov 256*256 – samotné číslo sa vypočíta ako bajt 1*256+bajt 2 do troch bajtov 256*256 – číslo sa sa vypočíta ako bajt 1*256^2+bajt 2*256+bajt 3 zo štrvtého bajtu použijeme len 7 bitov (8. je znamienkový) – 128*256*256
Reprezentácia typov II. l char: – je reprezentovaný jedným bajtom – 256 hodnôt – transformácia číselných hodnôt na znaky sa realizuje prostredníctvom ASCII tabuľky, kde každej numerickej hodnote zodpovedá jeden znak l boolean – postačuje 1 bit, no obvykle sa v prostredí Win 32 využíva celý byt. l real – pozostáva z dvoch častí: l mantisa – číslice určujúce presnosť čísla l exponent – násobok desiatky l napr. 1, 4587 E 20 predstavuje číslo 1, 4587 * 10^20 l mantisa: 1, 4587 l exponent: 20 l čím presnejšiu hodnotu požadujeme, tým viac bitov má mať mantisa l čím väčšie (menšie) číslo požadujeme, tým viac bitov má byť vyhradených pre exponent
Reprezentácia typov III. l l l l l Typ Real 48 Single Double Extended Comp Currency Rozsah 5. 0 x 10^-324. . 1. 7 x 10^308 2. 9 x 10^-39. . 1. 7 x 10^38 1. 5 x 10^-45. . 3. 4 x 10^38 5. 0 x 10^-324. . 1. 7 x 10^308 3. 6 x 10^-4951. . 1. 1 x 10^4932 -2^63+1. . 2^63 -1 -922337203685477. 5808. . 922337203685477. 5807 mantisa 15 -16 11 -12 7 -8 15 -16 19 -20 veľkosť 8 bytov 6 4 8 10 8 19 -20 8 comp je vlastne integer, no nie je ordinálny, preto sa uvádza medzi reálnymi typmi
Jednoduché úlohy na súbory l l l Hodnoty zadané v súbore typu integer načítajte do listboxu a nájdite medzi nimi maximum. Načítajte do listboxu riadky z textového súboru a do súboru ‘vysledok. txt’ uložte najdlhšie a najkratšie slovo. Pre zadaný text uložený v súbore vypíšte do listboxu všetky rôzne riadky, ktoré sa v ňom vyskytujú. Pre zadaný text uložený v súbore vypíšte do listboxu všetky rôzne slová, ktoré sa v ňom vyskytujú (slová sú oddelené medzerami). K rôznym slovám pridajte i početnosť – v samostatnom listboxe – prostredníctvom poľa – v tom istom listboxe – vypíšte slovo, ktoré sa vyskytuje najviac ráz
- Slides: 28