Adatbázisrendszerek I. File-szintű adattárolás C-ben. 1. gyakorlat

Hasonló dokumentumok
Adatbázisrendszerek I. Fájlszintű adattárolás C-ben

Programozás 6. Dr. Iványi Péter

A C programozási nyelv VI. Parancssori argumentumok File kezelés

Mérnöki programozás 7. Szerkesztette: dr. Vass Péter Tamás

Programozás alapjai C nyelv 8. gyakorlat. Mutatók és címek (ism.) Indirekció (ism)

Miről lesz ma szó? A PROGAMOZÁS ALAPJAI 1. Dinamikus változók. Dinamikus változók. Dinamikus változók. Dinamikus változók. 7.

Mutatók és címek (ism.) Programozás alapjai C nyelv 8. gyakorlat. Indirekció (ism) Néhány dolog érthetőbb (ism.) Változók a memóriában

Listák, szótárak, fájlok Listák, szótárak, fájlok

Programozás II. Fájlkezelés

5. Gyakorlat. struct diak {

Programozás alapjai C nyelv 5. gyakorlat. Írjunk ki fordítva! Írjunk ki fordítva! (3)

7. gyakorlat Sorozatok, Fájlkezelés

11. gyakorlat Sturktúrák használata. 1. Definiáljon dátum típust. Olvasson be két dátumot, és határozza meg melyik a régebbi.

Adatbázis rendszerek Gy: Az adattárolás fejlődése

Pénzügyi algoritmusok

A C programozási nyelv V. Struktúra Dinamikus memóriakezelés

Programozás alapjai 9.Gy: Struktúra 2.

A programozás alapjai 1 Rekurzió

Objektumorientált programozás Pál László. Sapientia EMTE, Csíkszereda, 2014/2015

OOP #14 (referencia-elv)

7/8. gyakorlat Karaktertömbök és sztringkezelés

Programozás alapjai 6. előadás. Wagner György Általános Informatikai Tanszék

OOP: Java 11.Gy: Enumok, beágyazott osztályok. 13/1 B ITv: MAN

6. gyakorlat Egydimenziós numerikus tömbök kezelése, tömbi algoritmusok

3. Osztályok II. Programozás II

10. ÓRA. Fájlok használata

1. Feladat: beolvas két számot úgy, hogy a-ba kerüljön a nagyobb

Dr. Pál László, Sapientia EMTE, Csíkszereda WEB PROGRAMOZÁS 6.ELŐADÁS. Fájlkezelés PHP-ben

Programozás I gyakorlat

Programozás I. gyakorlat

Tartalom Keresés és rendezés. Vektoralgoritmusok. 1. fejezet. Keresés adatvektorban. A programozás alapjai I.

Mutatók és mutató-aritmetika C-ben március 19.

Függvény pointer. Feladat: Egy tömbben soroljunk fel függvényeket, és hívjuk meg valahányszor.

Például számokból álló, egyszeresen láncolt lista felépítéséhez az alábbi struktúra definíciót használhatjuk:

Programozás alapjai C nyelv 9. gyakorlat. Rekurzió. Rekurzív algoritmus

1. Alapok. Programozás II

Keresés és rendezés. A programozás alapjai I. Hálózati Rendszerek és Szolgáltatások Tanszék Farkas Balázs, Fiala Péter, Vitéz András, Zsóka Zoltán

Programozási Nyelvek: C++

ELTE SAP Excellence Center Oktatóanyag 1

10. gyakorlat Tömb, mint függvény argumentum

Rekurzió. Programozás alapjai C nyelv 9. gyakorlat. Rekurzív algoritmus. Rekurzív algoritmus fajtái. Példa: n! (2) Példa: n!

C programozási nyelv Pointerek, tömbök, pointer aritmetika

HORVÁTH ZSÓFIA 1. Beadandó feladat (HOZSAAI.ELTE) ápr 7. 8-as csoport

Algoritmusok és adatszerkezetek gyakorlat 06 Adatszerkezetek

Programozás I gyakorlat

Rekurzió. Dr. Iványi Péter

II. Mérés SZÉCHENYI ISTVÁN EGYETEM GYŐR TÁVKÖZLÉSI TANSZÉK

Programozási nyelvek Java

Programozás 5. Dr. Iványi Péter

Programozás alapjai 8.Gy: Program struktúra

C programozás. 6 óra Függvények, függvényszerű makrók, globális és

Szövegek C++ -ban, a string osztály

Adatbázis Rendszerek II. 2. Ea: Gyakorló környezet

Struktúrák (struct) A struktúra szerkezetét meghatározó deklaráció általános formája:

Függvények. Programozás alapjai C nyelv 7. gyakorlat. LNKO függvény. Függvények(2) LNKO függvény (2) LNKO függvény (3)

Programozás alapjai C nyelv 7. gyakorlat. Függvények. Függvények(2)

Programozás I gyakorlat

10. gyakorlat Struktúrák, uniók, típusdefiníciók

Programozási nyelvek Java

Programozás II gyakorlat. 6. Polimorfizmus

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós május 6. Széchenyi István Egyetem, Gy r

Adatbázis Rendszerek II. 2. Gyakorló környezet

/* Az iter függvény meghívása és a visszatérő érték átadása a gyok változóba */ gyok = iter( n, a, e ) ;

Programozás II. segédlet

1. feladat Készítse el szövegszerkesztővel, majd mentse osztály.txt néven a következő tartalmú szöveges fájlt:

Információs Technológia

Programozás alapjai gyakorlat. 4. gyakorlat Konstansok, tömbök, stringek

Programozás I. gyakorlat

Nagy HF u tmutato 2011/2012 II. fe le v

Objektum Orientált Programozás. 11. Kivételkezelés 44/1B IT MAN

Programozás C nyelven FELÜLNÉZETBŐL elhullatott MORZSÁK. Sapientia EMTE

C++ programozási nyelv

Cekla. Készítette Doxygen Tue Sep :13:44

7. fejezet: Mutatók és tömbök

Járműfedélzeti rendszerek II. 3. előadás Dr. Bécsi Tamás

Programozás alapjai. (GKxB_INTM023) Dr. Hatwágner F. Miklós október 11. Széchenyi István Egyetem, Gy r

Pénzügyi algoritmusok

BME MOGI Gépészeti informatika 13.

C string műveletek (string.h alkalmazása)

Programozas 1. Strukturak, mutatok

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós április 4. Széchenyi István Egyetem, Gy r

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós március 3. Széchenyi István Egyetem, Gy r

STL gyakorlat C++ Izsó Tamás május 9. Izsó Tamás STL gyakorlat/ 1

A C programozási nyelv I. Bevezetés

A C programozási nyelv I. Bevezetés

500. AA Megoldó Alfréd AA 500.

Mit tudunk már? Programozás alapjai C nyelv 4. gyakorlat. Legnagyobb elem keresése. Feltételes operátor (?:) Legnagyobb elem keresése (3)

Fejlett programozási nyelvek C++ Iterátorok

Példák tematikus csoportosításban

Programozási segédlet

Programozás I. zárthelyi dolgozat

Dinamikus memóriakezelés Fájlkezelés

és az instanceof operátor

Bevezetés a programozásba I.

C++ programozási nyelv Konstruktorok-destruktorok

Programozás alapjai C nyelv 4. gyakorlat. Mit tudunk már? Feltételes operátor (?:) Típus fogalma char, int, float, double

Programozás Minta programterv a 1. házi feladathoz 1.

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán

Programozás II. 2. gyakorlat Áttérés C-ről C++-ra

SQL*Plus. Felhasználók: SYS: rendszergazda SCOTT: demonstrációs adatbázis, táblái: EMP (dolgozó), DEPT (osztály) "közönséges" felhasználók

Átírás:

Adatbázisrendszerek I. File-szintű adattárolás C-ben 1. gyakorlat Feladat: Tervezzen meg egy fájlszintű adatnyilvántartó rendszert és implementálja C nyelven. A tárolandó adatok: autó rendszáma, típusa, színe, gyártási éve és ára. 1. Adatszerkezet megtervezése typedef struct car { char rendszam[6]; char tipus[20]; char szin[10]; int gyart_ev; double ar; Car; Figyelem! Ha scanf függvénnyel történik az adatbeolvasás, a sztring nem tartalmazhat space-t. 2. Adattárolás fájlban C-ben az adatok tárolhatók ASCII szövegfájlban, vagy bináris fájlban. Fájl létrehozása: FILE *fopen(const char *fajl_nev, const char *megnyitas_mod); Megnyitási módok (szövegfájlok esetén): r (reading) olvasás w writing) írás a (append) hozzáfűzés r+ olvasás a fájl elejétől + írás w+ írás+olvasás, felülírjuk a fájlt a+ írás + olvasás, hozzáfűzünk Bináris fájloknál a betűk után még egy b betűt is oda kell írni, pl.: rb vagy wb+. Ha a fájl megnyitása sikerült egy FILE struktúrára mutató pointert kapunk vissza, ha nem sikerült, akkor NULL pointert. FILE *fp=fopen("cars.bin","ab"); if (!fp) { printf("error: cannot open file."); return -1; Fájl lezárása: int fclose(file *fp); A szöveges fájlokban (txt) olvasható formátumban, soronként vannak tárolva az adatok. Egy sor állhat egyetlen karakterből: int fputc( int c, FILE *fp ); vagy egy sztringből: int fputs( const char *s, FILE *fp ); int fprintf(file *fp,const char *format, ); A szövegfájl tartalmának olvasásához az alábbi függvények használhatók. Egy karakter olvasása: int fgetc( FILE * fp );

Sztring olvasása: n-1 karakter (+a lezáró \0 ) olvasása. Ha újsor karaktert vagy fájl vége jelet olvas, a függvény befejezi futását : char *fgets( char *buf, int n, FILE *fp ); Sztring olvasása (space-ig!): int fscanf(file *fp, const char *format, ); Bináris fájlokban az adatok nem olvasható formátumban tárolódnak. Az eltárolt objektumok nem csak szekvenciálisan érhetők el, azaz az aktuális fájl pozíció a kívánt helyre mozgatható. A nagyobb adategységek (tömbök, struktúrák) írása, olvasása egyszerűbb (nem igényel sztringkezelő műveleteket). Jelen esetben a struktúra objektum egyetlen függvényhívással írható, olvasható, amelynek adattagjaira a szokásos módon hivatkozhatunk. Szemben a szövegfájllal, ahol a struktúra adattagjait egy sztringbe összefűzve írhatjuk a fájlba, illetve olvashatjuk ki onnan. Bináris fájlok írása és olvasása: size_t fwrite(const void *ptr, size_t meret, size_t darab, FILE *fp); size_t fread(void *ptr, size_t meret, size_t darab, FILE *fp); Egy autó struktúra fájlba írása: fwrite(&car, sizeof(car), 1, fp); Egy autó struktúra fájlbó olvasása: Pozicionálás fájlban: int fseek(file * fp, long int offset, int origin); Az első paraméter a FILE pointer, a második a pozíció eltolásának mértéke. Ez az elem bájtokban mért nagyságának egész számú többszöröse. Az origin azaz az eltolás kezdete a következő makrókkal adható meg: SEEK_SET, SEEK_CUR és SEEK_END. Ezek jelentése: fájl elejétől, aktuális pozíciótól, illetve a fájl végétől számítjuk az offsetet, ami negatív is lehet. 3. Adatokon végrehajtandó műveletek: 1. Adatok listázása 2. Új adat felvitele 3. Adat törlése 4. Keresés 3.1 Listázás A fájlt az elejétől kezdve végig kell olvasni és minden adatot kiírni a képernyőre. Azaz a fájl megnyitása után (megnyitási mód: rb) az elejéről indulva minden ciklusiterációban eggyel előre mozgatjuk a fájl pointert ( i a ciklusváltozó) és kiolvassuk az aktuális adatot. De mi lesz a ciklus kilépési feltétele? Addig dolgozom fel a tárolt adatokat, amíg el nem érek a fájl végére. printf(...); A fájl méretének meghatározása úgy történik, hogy a végére pozicionálunk és az aktuális pointer pozíció értékét elosztjuk a struktúra méretével. fseek(fp, 0L, SEEK_END); int filesize = ftell(fp)/sizeof(car);

3.2 Új adat felvitele Adatfelvitelhez a fájlt hozzáfűzés módban (ab) nyitjuk meg. Egymás után bekérjük a struktúra adattagjait, majd az fwrite függvénnyel az egész struktúrát egyben eltároljuk. fwrite(&car, sizeof(car), 1, fp); Ennél a feladatnál a legfontosabb feladat az adatbevitel ellenőrzése. A megadott adatok szintaktikai ellenőrzéséhez azt kell tudni, hogy a scanf függvény visszatérési értéke a sikeresen beolvasott értékek száma. De van-e lehetőség az adatok szemantikai ellenőrzésére? Jelen esetben a rendszám az autók egyedi azonosítója. Tehát az adatok fájlba írása előtt meg kell nézni, hogy a megadott rendszám létezik-e már. Vagyis végig kell olvasni a fájlt és minden tárolt rendszámot össze kell hasonlítani azzal, amit most szeretnénk felvinni. Ha nincs találat, a rendszám egyedi és a megadott adatok eltárolhatók. if (strcmp(car.rendszam, rsz) == 0) return 1; /* már létezik */ else return 0; /* nem létezik */ 3.3 Adat törlése Egy autó struktúra eltávolítása a fájlból nem triviális feladat. Szükségünk van egy segédfájlra: ebbe átmásoljuk a törlendő struktúrán kívül az összes többi adatot. Majd az eredeti fájlunkat újraírási módban (wb) megnyitva, visszaírjuk ide a segédfájl tartalmát. Az újraírási mód azt jelenti, hogy a nem létező fájl létrejön, a létező pedig felülíródik. Figyelem! A segédfájlt mindig újra kell írni, és mivel vissza is kell olvasni a tartalmát a megnyitási mód: wb+. 1. lépés: segédfájlba átírás if (strcmp(car.rendszam, rendszam)!= 0) /* ha nem a törlendő */ fwrite(&car, sizeof(car), 1, fp_tmp); 2. lépés: visszaírás az eredeti fájlba for (i=0; i<filesize-1; i++) { fseek(fp_tmp,sizeof(car)*i,seek_set); fread(&car,sizeof(car),1,fp_tmp); fwrite(&car, sizeof(car), 1, fp); 3.4 Keresés A keresésnél először azt kell eldönteni, hogy mi alapján keresünk (rendszám, típus, stb.). Mivel a rendszám egyértelműen kijelöl egy struktúrát, ha rendszám szerint keresünk biztosan 1 autó lesz a keresés eredménye. Ha a többi adattag szerint akarunk szűrni, valószínűleg egynél több találatot kapunk. A rendszám alapján történő keresésnél ugyanaz a kód használható, mint a rendszám ellenőrzésnél:

if (strcmp(car.rendszam, rsz) == 0) kiir(); /* talált */ else printf("nem talált."); A feladat megoldását a C_bin_fajlkezeles.c forráskód tartalmazza. Önállóan megoldandó feladatok: 1. Adatfelvitel előtt végezzünk szemantikai ellenőrzést a gyártási évre: 1996 <= gyártási év <= 2016. 2. Számítsuk ki az autók átlagárát. 3. Kérdezzük le a piros autók darabszámát. 4. Keressük meg a legdrágább autót.

Adatbázisrendszerek I. File-szintű adattárolás C-ben 2. gyakorlat Egészítsük ki az 1. gyakorlat feladatát: az autók mellett tároljuk el a tulajdonosok adatait is külön fájlban. Ehhez definiáljunk egy új struktúrát. typedef struct tulaj { Tulaj; int id; char nev[20]; char cim[50]; A definícióból látható, hogy minden tulajdonos struktúrához hozzárendelünk egy sorszámot (int id). Ez segít az adatsorok egyértelmű beazonosításban. Hiszen sok Szabó Tamás él Magyarországon, akik akár ugyanazon a lakcímen is élhetnek (apa és fia). Ez a sorszám akkor használható azonosítóként, ha biztosítjuk, hogy minden sorszámot csak egyszer osszunk ki. A tulajdonosok adatainak kezelése egyébként az autó adatok kezeléséhez hasonló (listázás, felvitel, törlés, keresés). Azért, hogy a két feladatrész elkülönüljön, az adatkezelő műveleteket megvalósító függvényeket külön forrásfájlokban (modulokban) definiáljuk. Így a két nyilvántartást külön, egymástól függetlenül vezetjük. Ha azt szeretnénk, hogy az autók a tulajdonosaikkal össze legyenek kapcsolva, azaz az autókat lekérdezve a tulajdonos adatait is lássuk, illetve a tulajdonosok listáján a hozzájuk kapcsolódó autók adatai is szerepeljenek, a struktúra definíción kell változtatni. Ha a tulajdonos struktúrába felveszek egy autója rendszáma adattagot, akkor ez azt jelenti, hogy egy emberhez csak egy autót tudok kötni. Hogyan tudom megadni, ha több autója van? 1. Vegyem fel többször a tulajdonost a nyilvántartásba? 2. Az autója rendszáma adattag legyen tömb? Mekkora legyen a tömb mérete? Egyik sem tökéletes megoldás, mert felesleges memóriafoglalással jár és például a tulajdonos több példányban történő eltárolása a törlésnél problémát okozhat. Próbáljuk meg inkább az autó struktúrában tárolni a tulajdonost. Ha tulajdonos alatt az autó üzembentartóját értjük, akkor igaz az az állítás, hogy minden autónak csak egy üzembentartója van. Felmerül a kérdés, hogy akkor az autó struktúrán belül legyen a tulajdonos struktúra definiálva (beágyazott struktúra)? Ha abból indulunk ki, hogy minden autónak van tulajdonosa, akkor igen. De vizsgáljuk meg a kérdést a tulajdonos szemszögéből is. Minden tulajdonosnak egy autója van? Ha nem, akkor minden autó objektumnál újra fel kell venni az adatait és el kell tárolni. Tehát célszerű a két struktúrát külön definiálni és az autó struktúrában csak egyetlen adattaggal hivatkozni a tulajdonosára. Milyen típusú legyen ez az adattag? Célszerű a tulajdonost egyértelműen azonosító adatot választani (jelen esetben az id adattagot). typedef struct car { Car; char rendszam[7]; char tipus[20]; char szin[10]; int gyart_ev; double ar; int tulaj_id; //új adattag: autó tulajdonosa

Ily módon a két nyilvántartás összekapcsolását megoldottuk. A feladat megoldását a C_fajlkezeles_2 C projekt tartalmazza. Önállóan megoldandó feladatok: 1. Vezessünk be ellenőrzést az autók felvitelénél: csak létező (a tulajdonos fájlban megtalálható) tulajdonos azonosítót lehessen megadni. 2. A tulajdonosok törlése előtt végezzünk ellenőrzést: ne lehessen olyan tulajdonost törölni, akire van hivatkozás az autó nyilvántartásban (azonosítója szerepel az autó tulajdonosok között). 3. Készítsünk összefésült listákat: 3.1 Az autók listázásánál a tulajdonos adatait is lássuk. 3.2 A tulajdonosok listázásánál a hozzájuk tartozó autók adatai is jelenjenek meg. 4. Adatmódosítás. Itt azt kell eldönteni, hogy csak teljes struktúra legyen módosítható, vagy az egyes adattagok külön. Mindenképpen be kell olvasni egy rendszámot és meg kell keresni az adott rendszámú autó adatait. Felkínálhatjuk, hogy a felhasználó válassza ki melyik adattagot kívánja módosítani (egyszerre csak egyet); vagy az új adat felvitelhez tartozó programkódot felhasználva beolvassuk az összes adattag új értékét. Akárhogy is döntünk, vagy az aktuális fájl pozícióra kell ráírni a módosított adatokat, ekkor a fájl megnyitási mód: r+ ; vagy a törlésnél használt segédfájlos megoldást kell alkalmazni. 5. Csökkentsük az összes autó árát 10%-al.