Gyakorlat

Programozási tételek szekvenciális fájlokra „hangolva”

Feladat

Az alap feladat

Egy személyi adatokat tartalmazó „adatbázis” feldolgozása a feladat. A fájl adatait mindenekelőtt –ellenőrzésképpen– izlésesen kiírjuk a képernyőre!
Az „izlésesen” ezt jelenti:

     vezetéknév(20)   |   keresztnév(20)   | sz.sz.(11)

Például:

  Neumann             |János               |10312281234

Megjegyzés: a mezőtartalom mögötti szám a mező hosszát jelöli (karakterekben); „sz.sz.”=„személyi szám”.

A bemeneti fájl egy elemének típusa

Típus
  TSzemély=Rekord(
    vnév,knév:Szöveg(20) [legfeljebb 20 jelből álló szöveg]
    szsz:Szöveg(11) [személyi szám: pontosan 11 jelből álló szöveg]
  )

Megjegyzés: Pascalban a Szöveg(h)-nak a String[h] felel meg.

A „lényegi” feladatok

  1. Készítsen izléses, lapozott listát a tárolt adatokról, a képernyőre!
    Lapozott: egy lapra legfeljebb 20 sort írjon ki! Az utolsó lap állhat csak 20-nál kevesebb sorból! Egy adott lap kiírásakor billentyűre várjon a program! Izléses: minden lapon az első sora fejléc legyen, az alábbi szöveggel és hosszakkal:
          #  |     Vezetéknév     |     Keresztnév     | Év ||Nap|Nem
          4  |         20         |         20         | 4  |2 | 3 | 3 
    Például:
          #  |     Vezetéknév     |     Keresztnév     | Év ||Nap|Nem
            1|Neumann             |János               |1903|12|28 |Ffi
          ...|...                 |...                 |... |..|...|...
           19|Roberts             |Julia               |1967|10|28 |
    Képernyőterv:
       
  2. Van-e a fájlban olyan személy, akinek a születésnapját a mai nap (2015.03.02.) 8 napos környezetében ünnepelhetnénk? (Segítségként súgok: a kiinduló algoritmust megtalálja a vonatkozó előadás 18. diáján. Figyelje meg az itt alkalmazott ún. előreolvasási technikát „működés” közben.)
  3. Válogassa szét egy-egy fájlba a hölgyeket és az urakat! (Segítségként súgok: a kiinduló algoritmust megtalálja a vonatkozó előadás 26. diáján.
  4. Határozza meg hányan születtek az egyes hónapokban! Az eredményt izlésesen írja ki a képernyőre és egy fájlba is!

Természetes elvárás a megvalósítással szemben, hogy

A String-kezeléshez ajánlom figyelmében a már ajánlott anyagot: Stringkezelo_fuggvenyek.pdf.
Néhány kész (típusos/karakteres) adatfájl: minta.dat/minta.txt, nobel.dat/nobel.txt.

Kiegészítő feladat

Fájl-konverziós feladat

Az előbbi feladathoz tartozó ún. típusos fájl elkészítése már nem megy semmilyen szövegszerkesztővel (pl. a Geany-vel). Ezért ezt le kell gyártani! Két út kínálkozik erre:

  1. Egy program klaviatúráról bekéri az adatokat, és rögvest a megfelelő típusú fájlba írja. A lényegi kódot itt olvasható. Értse meg, és egészítse ki a hiányzó részekkel!
    Type
      TSzemely=Record
        vnev,knev:String[20];
        szsz:String[10];
      End;
      TSzemelyFajl=File of TSzemely;
    Var
      szemely:TSzemely;
      kiF:TSzemelyFajl; {kimeneti adatfájl}
      s:String;         {a beolvasáshoz}{… a fájl nevet beolvastuk már …
       … a kiF-et megnyitottuk írásra …
       a beolvasott adatok helyességét most nem ellenőrizzük:}
      Write('Vezetéknév:');    Readln(s); szemely.vnev:=Copy(s,1,20);//szemely.vnev:=s
      Write('Keresztnév:');    Readln(s); szemely.knev:=Copy(s,1,20);//szemely.knev:=s
      Write('Személyi szám:'); Readln(s); szemely.szsz:=Copy(s,1,11);//szemely.szsz:=s
      Write(f,szemely);
      …
      {… a fájlt lezártuk …}
  2. Előre elkészítjük az adatokat tartalmazó karakteres fájlt (Text). Ehhez felhasználható valamilyen egyszerű szövegszerkesztő (pl. a Geany).
    Annak érdekében, hogy az egyes adatrekordok mezőit meg tudjuk különböztetni, megegyezünk valamilyen mezőelválasztó jelben. Értelemszerűen ez a jel nem fordulhat elő egyetlen mező részeként! A fenti feladathoz több esélyes ilyen jel létezik. Lehet pl. pontosvessző (mert ez az alapja az ún. csv-formátumnak is).
    Egy programmal ilyen szerkezetű sorokból álló fájlból beolvassuk az adatokat, majd rövest kiírjuk a fenti típusos fájlba.
    Egyetlen „nehézség” a beolvasott szövegsor mezőkre bontása. Erre találunk alább egy megoldást:
    Var
      beF:Text;         {bemeneti fájl}
      szemely:TSzemely;
      kiF:TSzemelyFajl; {kimeneti adatfájl}
      s:String;         {a beolvasáshoz}
      hol:Integer;      {a karakterkereséshez}{… a fájl neveket beolvastuk már …
       … a beF-et olvasásra, a kiF-et írásra megnyitottuk …
       a beolvasott adatok helyességét most nem ellenőrizzük:}
      Readln(beF,s); {s:egy teljes sor}
      //s-et mezőkre szedjük a pontosvesszőknél:
      hol:=Pos(';',s); szemely.vnev:=Copy(s,1,hol-1); s:=Copy(s,hol+1,Length(s)-hol);
      hol:=Pos(';',s); szemely.knev:=Copy(s,1,hol-1); s:=Copy(s,hol+1,Length(s)-hol);
      szemely.szsz:=s;
      Write(f,szemely);
      …
      {… a fájlokat lezártuk …}

Némileg egyszerűsíthetők a szövegmanipulációk, ha felhasználja string-kezelő rutinjaimat. Ezt az inklúd-állományt a „szokásos” módon csatolhatja a forráskódjához.

Házi feladatok

  1. Befejezni a gyakorlaton elkezdett programo(ka)t (a specifikáció és az algoritmus a kód elején, kommentárban).
  2. Válogassa ki egy fájlba egy adott dátum-intervallumba eső, adott nemű személyeket! A dátum-intervallum és a nem klaviatúráról olvasandó be!
    Adjon lehetőséget arra, hogy a nem „tetszőleges” legyen! Például úgy, hogy a kérdésre helyes válaszként elfogadja az 'F' jelet ('férfi' értelemben), a 'H' jelet ('hölgy' értelemben), valamint az üres szöveget ('tetszőleges' értelemben).


Szlávi Péter