Darbas su failais Spausdinti
( 11 Votes )

Parašė Vidmantas Šarkys   

Iki šiol kūrėme ir nagrinėjome pavyzdžius, kuriuose rašant ar skaitant tekstą naudojamasi ekranu. Tai yra gan patogu, kadangi iškart matome rezultatą. Tačiau, pavyzdžiui, valstybinio informatikos egzamino programų reikalavimuose draudžiama naudoti komandas ekranui - visi duomenys turi būti tekstiniuose failuose. Šiame skyriuje apžvelgsime, kaip skaityti ir rašyti į tekstines rinkmenas. 

Pirmiausiai turime susikurti tekstinį failą. Kad būtų patogiau, patartina ir tekstinį, ir programos failą išsaugoti vienoje direktorijoje. Tarkime, jog sukūrėme tekstinį failą darbalaukyje. Ten pat išsaugokime ir programos failą. Tai atrodys štai taip.

Suprantama, jog tekstinis failas bus tusčias, tad reikės jį užpildyti. Įrašykime jame 2 skirtingus skaičius : 7 ir 5. Tuoj nuskaitysime šiuos skaičius, tačiau prieš tai reikėtų pažymėti keletą dalykų. Skaičiai bus nuskaitomi kaip kintamųjų reikšmės, tad po kiekvieno skaičiaus reikia padėti tarpą. Tai elementaru, kadangi eilutė 5 6 8 reikš 3 skiritngus skaičius, o 568 - tik vieną triženklį skaičių. Jeigu skaitmenys yra skirtingose eilutėse, jie traktuojami kaip atskiri skaičiai, tad tarp jų palikti tarpą nėra reikalo. Lygiai ta pati taisyklė galioja ir su žodžiais bei sakinio tipo kintamaisiais: jeigu į tekstinį failą raides "supilsime" be jokios tvarkos, gali kilti problemų nuskaityme. 

Sukurkime programą, kuri nustatytų, kuris iš tekstiniame faile esančių dviejų skaičių yra didesnis.

program tekstinis;
 var x, y : integer;
 txt : text;
function did : integer;
Begin 
 If x > y then did := x 
             else did := y;
end;
Begin
assign(txt, 'tekstinė_rinkmena.txt');
Reset(txt);
Read(txt, x);
Read(txt, y);
WriteLn('Didesnis skaičius : ', did);
ReadLn;
close(txt);
end.

Žinodami, jog naudosime tekstinę bylą, turime sukurti kintamąjį, kuris jai "atstovautų". Kintamųjų apraše tam reikalui pasirinkome kintamąjį "txt". Tačiau kol kas šis kintamasis su mūsų tekstiniu failu nėra susietas. Tai padarome 10-oje eilutėje sakiniu "assign". Skliausteliuose parašome kintamąjį, kuriam priskirsime failą ir norimo failo adresą. Pastebėkime, jog failo adresas rašomas teksto kabutėse. Kaip jau minėjome, sukūrėme tekstinį failą toje pat vietoje, kaip ir mūsų programa, tad mums užteko parašyti to failo pavadinimą. Kitais atvejais, kai failas egzistuoja kitur, reikia nurodyti jo buvimo vietą. Tai atrodytų maždaug taip : 'C:\Desktop\tekstinė_rinkmena.txt' . 

Po priskyrimo turime nurodyti, ką veiksime su tekstiniu failu. Yra du variantai : rašysime į jį arba skaitysime iš jo ( būtina pasirinkti vieną). Komanda "reset(txt)" lems tai, jog iš failo bus skaitoma ir jo turinys nebus keičiamas. O komanda "rewrite(txt)" paruoštų failą rašymui į jį, tačiau visi duomenys tuo metu esantys faile būtų ištrinti. Šiuo atveju mes tenorėjome skaityti iš failo.

Viena dažniausiai pasitaikančių ir klaidų - failo neuždarymas. Kartais įsijautę į užduotį tiesiog pamirštame tai padaryti, tačiau uždaryti failą yra būtina, kadangi, kitu atveju, jis liks tuščias. Tai padarėme priešpaskutinėje eilutėje naudodami komandą "close(txt)".

Prisiminkime mūsų programos paskirtį : nuskaityti du skaičius iš failo ir vėliau parašyti ekrane didesnįjį. Nuskaitymą atliekame 12 ir 13 eilutėse. Atkreipkime dėmėsį, jog skaitydami iš failo turime nurodyti, iš kokio failo tai darome. Kartais galima vienu metu dirbti su daugiau nei viena tekstine rinkmena, tad turime nurodyti, iš kokio failo ir kokius kintamuosius norime nuskaityti, ar, kitu atveju, parašyti. Nuskaitę du skaičius galime atlikti funkciją ir parašyti ekrane didesniojo skaičiaus reikšmę.

Lygiai kaip nuskaityti, duomenis į tekstinį failą galime ir parašyti. Sukurkime sudėtingesnę programą, kuri iš duomenų faile esančių skaičių išrinktų didžiausiąjį, o rezultatų faile parašytų tą skaičių ir jo numerį. Duomenų faile esantys skaičiai:

sk

program didziausias;
type masyv = array[1..100] of integer;
       didz = record
        sk : integer;
        nr : integer;
var A : masyv;
     d : didz;
     duom, rez : text;
     n : integer;
Procedure nuskaitymas; //procedūra, skirta skaičiams nuskaityti iš failo
 var i : integer;
Begin
 assign(duom, 'tekstas.txt'); Reset(duom);
 ReadLn(duom, n);
 For i := 1 to n do
 Read(A[i]);
 close(duom);
end;
Procedure didziausio_radimas; //randame didžiausią narį ir jo numerį
 var i : integer;
Begin
 d.sk := 0;
 For i := 1 to n do
  If A[i] > d.sk then 
   begin
    d.sk := A[i];
    d.nr := i;
   end;
end;
Procedure rasymas; //surašome atsakymus į rezultatų failą
Begin
 assign(rez, 'rezultatai.txt'); rewrite(rez);
 WriteLn(rez, 'Didžiausias skaičius yra ', d.sk');
 WriteLn(rez, 'Šio skaičiaus numeris yra ', d.nr');
 close(rez);
end;
Begin
nuskaitymas;
didziausio_radimas;
rasymas;
end.

Į šį pavyzdį sutalpinome visa, ką išmokome nagrinėdami fps programų pavyzdžius. Todėl suprantama, jog tam, kad suprasti šią programą, gali prireikti šiek tiek laiko. Reikėtų atkreipti dėmesį į tai, jog tekstiniame duomenų faile skaičius 15, esantis viršuje kitų, reiškia, jog mūsų tekstiniame faile yra 15 skaičių, o su likusiais neturi nieko bendro. Tai padarėme tam, kad galėtumėme nuskaityti visus skaičius naudodami ciklą "for" (naudodami šį ciklą turime tiksliai žinoti skaičių kiekį). Procedūroje "didziausio_radimas" pasinaudojome algoritmu, naudojamu rasti didžiausiai reikšmei masyve. Tuo pat metu suradome ir to skaičiaus numerį, kadangi masyvo reikšmės numerį atitinka ciklo kintamasis "i". Galiausiai liko tik surašyti duomenis į rezultatų failą, kur neaiškumų kilti tikrai neturėjo.

Yra dar 2 svarbūs su tekstiniais failais susiję operatoriai : "eol" ( end of line ) ir "eof" ( end of file ). Kam jie reikalingi nesunku suprasti išvertus jų reikšmes į lietuvių kalbą. "eol" yra eilutės, o "eof" - failo pabaigos indikatorius. Praeitame pavyzdyje nuskaitėme skaičius su "for" ciklu, tad turėjome žinoti, kiek skaičių bus. Naudojantis "eof" to mums nebūtina žinoti. Sukurkime paprastą pavyzdį tam iliustruoti. Tekstiniame faile turime 3 skaičius, parašytus skirtingose eilutėse, ir norime parašyti jų sumą ekrane.

program suma;
 var x, suma: integer;
      txt: text;
Begin
 suma := 0;
 assign(txt, 'failas.txt'); Reset(txt);
 While not eof(txt) do
  Begin
   ReadLn(x);
   suma := suma + x;
  end;
 close(txt);
WriteLn('Skaičių suma - ', suma);
ReadLn;
end.

Atkreipkime dėmesį į 7, 8 ir 9 eilutes. Jas galime perskaityti taip : kol nepriėjome failo "txt" pabaigos, kaskart atliekame šiuos veiksmus: nuskaitome kintamąjį x ir sumą papildome šio kintamojo reikšme. Po šių veiksmų mums telieka parašyti atsakymą į ekraną.

Šis skyrius apie Free Pascal yra paskutinis. Išsiaiškinome daugybę programų pavyzdžių ir Free Pascal elementų. Visa tai, ką nagrinėjome, tėra patys FPS pagrindai, tačiau, net neabejoju, kad įsisavinę juos galėsite be vargo kurti sudėtingesnes programas ar pasiruošti valstybiniams egzaminams. Jei kyla neaiškumų FPS kalboje, apsilankykite mūsų forume - mielai jums padėsime. Sėkmės programavimo pasaulyje!