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 az oldal aljáról 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.
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!


ċ
András Lutter,
2014. nov. 23. 2:22
ċ
András Lutter,
2014. nov. 23. 2:35
ċ
András Lutter,
2014. nov. 23. 2:41
Comments