10. fejezet: Fájlkezelés
Bár sok programnak megvan a maga bináris fájlformátuma, mellyel az alább leírtaknál hatékonyabban tud dolgozni, ebben a fejezetben csak azt a fájlformátumot vesszük, amelyet minden program ugyanúgy kezel. Ez a szöveges fájl. A szöveges fájl csak karaktereket tartalmaz, és sorokra van tagolva. Az ékezetes karaktereket azonban egy szöveges fájlban is többféleképpen lehet tárolni.
A szöveges fájl műveletei: új fájl létrehozása, fájl elejére állás, következő adat beolvasása, adat írása a szöveges fájl végére. Emiatt az adatokat csak sorban tudjuk beolvasni, az utolsó sort csak akkor, ha már beolvastuk az összes előtte lévőt.
A fájlkezelés utasításai
Fájl deklarálása: létre kell hoznunk egy text
típusú változót, az összes fájlműveletben ezt fogjuk használni.
Ezután hozzá kell rendelni a változóhoz egy adott fájlt annak útvonala segítségével: assignfile(fájl,útvonal)
Megnyitás olvasásra (a fájlt vagy írásra, vagy olvasásra nyitjuk meg): reset(fájl)
Megnyitás írásra (ez új fájlt hoz létre, ha van már ilyen, azt törli): rewrite(fájl)
Megnyitás írásra létező fájlnál úgy, hogy a végéhez fűzünk adatot: append(fájl)
Fájl törlése: erase(fájl)
Olvasás: read/readln(fájl,változók)
Írás: write/writeln(fájl,kifejezések)
Vége van-e a fájlnak (beolvastuk-e az utolsó adatot, függvény, igaz/hamis): eof(fájl)
Vége van-e egy sor beolvasásának (függvény): eoln(fájl)
Fájl lezárása (erre főként írásnál van szükség, hogy az utolsó adatok is bekerüljenek a fájlba): closefile(fájl)
A read
és write
utasításokat úgyanúgy kell használni, mint amikor a billentyűzetről olvasunk és a képernyőre írunk, csak most megadjuk a fájlt is.
Példák olvasásra és írásra
A következő példákhoz már fájlra is szükség lesz. Szöveges fájlt legegyszerűbben a Windows Jegyzettömb alkalmazásával készíthetünk, de bármilyen szövegszerkesztő megfelel, ha a Mentés másként, szöveges fájl (txt) lehetőséget használod.
Most a fájlt is egy programmal hozzuk létre. A fájlok alapértelmezett helye (relatív útvonal megadásával, pl. 'proba1.txt') a projekt mappája, de teljes útvonal megadásával (pl. 'c:\programozas\fajl\proba.txt') más mappát is használhatunk.
A fájlnevekben szándékosan nem használok ékezetet. Ennek oka, hogy a Lazarus alapértelmezetten utf-8 kódolást használ a szerkesztőben. Ezt átállítottuk cp852-re a konzolablakban megjelenő karakterek miatt. A fájlrendszer azonban egy harmadik fajta kódolást használ (cp1250/ANSI). E kódlapok között lehet megfelelő függvényekkel konvertálni, de egyszerűbb, ha most mellőzzük az ékezeteket.
A fájl előállítása:
VAR f:text; i:integer; BEGIN assignfile(f,'proba1.txt'); rewrite(f); for i:=1 to 10 do writeln(f,i,' ',random(100)); closefile(f); END.
A most elkészült fájl soronként két számot tartalmaz, szóközzel elválsztva:
1 79
2 13
...
10 7
Ha egy sorban több szám van szóközzel elválasztva, ezeket beolvashatjuk így:
readln(f,a,b);
Vagy:
read(f,a); readln(f,b);
Vagy:
read(f,a); read(f,b); readln(f);
Az adatok beolvasásánál ha tudjuk előre, hány sor következik, használhatunk for-ciklust. Ha nem, vizsgálnunk kell, mikor van vége a fájlnak. A következő program kiírja a sorok második számainak összegét:
VAR f:text; s,a,b:integer; BEGIN assignfile(f,'proba1.txt'); reset(f); s:=0; while not eof(f) do begin readln(f,a,b); s:=s+b; end; closefile(f); writeln(s); write('enter:'); readln; END.
Látható, hogy a második számokhoz úgy jutunk el, hogy az elsőket is beolvassuk.
Végül nézzük, hogy lehet egy fájlból egy másikat előállítani. Ez a program leszedi minden sorból az első számot, és csak a másodikat írja fájlba:
VAR f,g:text; a,b:integer; BEGIN assignfile(f,'proba1.txt'); assignfile(g,'proba2.txt'); reset(f); rewrite(g); while not eof(f) do begin readln(f,a,b); writeln(g,b); end; closefile(g); closefile(f); END.
Szöveg a fájlban
Ha a fájl egy sorából szöveget szeretnénk beolvasni a readln(f,s)
utasítással (s
string típusú), az egy teljes sort beolvas. Ha a sor szóközöket tartalmaz, akkor azok is bekerülnek a stringbe. Ekkor nem tudjuk a szóközzel elválasztott szavakat külön változóba tenni. A beolvasott string szavakká darabolásával a következő fejezetben foglalkozunk.
Kivétel, ha a sor számokat és szöveget tartalmaz, és a számok a szöveg előtt vannak. Ekkor a szóközzel elválasztott számokat még külön be tudjuk olvasni. Ha pl. a sor tartalma:
3 2 1 rajt cél
akkor a readln(f,a,b,c,s)
utasítás beolvassa külön a 3 számot, de az utána következő két szót már egyben, s
-be.
Ha előbb van a szöveg, és utána a számok, akkor egyetlen stringbe tudjuk csak őket beolvasni. Ilyenkor a pos
, copy
függvényekkel megkereshetjük a szóközt, és kivághatjuk a szóközök közötti részt. Vagy használhatjuk a Free Pascal fejlett szövegdaraboló eljárásait, a következő fejezetből.
Feladatok
A következő feladatok bemeneti fájljait előállíthatod a Jegyzettömbbel is, de mellékeltem mintafájlokat, amelyeket a linkeken letölthetsz. Ne felejtsd ezeket a projekt mappájába másolni!
41. Írj programot, a mely megszámolja, hány szöveges sor van egy fájlban (feladat1.txt)! Tipp: minden sort be kell olvasni.
42. Számold meg a fájlban (feladat1.txt) lévő e-betűket! Tipp: olvasd be a sorokat, majd minden sorban számold meg az e-ket.
43. Készíts kimeneti fájlt, mely tartalmazza az eredeti fájlban (feladat1.txt) a sor számát és azt, hogy hány karakter hosszú!
44. Írj programot, mely egy egész számokat tartalmazó fájlt (feladat2.txt) fordított sorrendben kiír a képernyőre! A fájlban soronként egy szám van, legfeljebb 100 db. Ehhez a számokat el kell tárolnod egy tömbben./p>
45. Egy fájl (feladat3.txt) első sora egy számot tartalmaz, az utána következő sorok számát. A többi sorban két-két szám van szóközzel elválasztva. A program írja ki a számpárok szorzatának összegét!