460 likes | 553 Views
Programozás I. Adatállományok. dr Póder Margit f. docens Rendszer és Szoftvertechnológia Tanszék. 7. Adatállományok kezelése. Szöveges állományok: A szöveges file tetszőleges hosszúságú sorokból épül fel, a sor végét (MS-DOS állományok esetén) CR/LF zárja,
E N D
Programozás I. Adatállományok dr Póder Margit f. docens Rendszer és Szoftvertechnológia Tanszék
7. Adatállományok kezelése • Szöveges állományok: • A szöveges file tetszőleges hosszúságú sorokból épül fel, • a sor végét (MS-DOS állományok esetén) CR/LF zárja, • az állomány végét az EOF vezérlő karakter jelzi. • Például ilyenek a C++ forrásfileok, a txt kiterjesztésű fileok, stb. • Bináris állományok: • A bináris állományok byteokból épülnek fel. (A szöveges állomány is feldolgozható, mint bináris file.) • . Számítástechnika Tanszék
7. Adatállományok kezelése • Bináris állományok: • A bináris állományok byteokból épülnek fel. (A szöveges állomány is feldolgozható, mint bináris file.) • Alapvető különbség van a két file-típus között pl. a számok tárolásában. • A 2002 egy szöveges állományban a ’2’, ’0’, ’0’, ’2’ karakterek sorozatával kerül letárolásra, míg bináris állományban a szám a short int típusnak megfelelően, 2 byton kerül letárolásra úgy, ahogyan a memóriában megjelenik. • Példa: • €?..\MUNKA\BINFILE.CPPĽ???TC86 Borland C++ 3.1ú??ů?w??éfµ“,..\MUNKA\BINFILE.CPPë'é@ĘC:\BORLANDC.310\INCLUDE\CONIO.H„'é@ĘC:\BORLANDC.310\INCLUDE\_DEFS.H{'??é@ĘC:\BORLANDC.310\INCLUDE\STDIO.Hy(??é@Ę C:\BORLANDC.310\INCLUDE\_NFILE.H- Számítástechnika Tanszék
7. Adatállományok kezelése • A file-kezelés lépései: • 1. a file-t azonosító mutató definiálása • 2. az állomány megnyitása • 3. az állomány tartalmának feldolgozása file-műveletek (olvasás, írás, pozicionálás, stb. ) felhasználásával. • 4. az állomány lezárása. Számítástechnika Tanszék
7. Adatállományok kezelése • A file mutató definiálása • A programban mindegyik felhasználni kívánt állományhoz egy külön file mutatót kell létrehozni. • FILE * típusú file-mutató azonosítja az állományt. • A definició: • #include <stdio.h> • ..... • FILE * f1 Számítástechnika Tanszék
7. Adatállományok kezelése • A file megnyitása • A háttértárolón lévő file tartalmához csak a file megnyitása után férhetünk hozzá. • A megnyitáskor meg kell adni a file típusát (szöveges vagy bináris) • és a hozzáférés módját. • A megnyitás általános formája: • FILE *fopen (const char *filename, const char *mode); • ahol • filename az állomány neve, ahogyan az operációs rendszerben használjuk (tartalmazhatja a teljes elérési útvonalat is, ekkor figyelni kell arra, hogy a \ karakter string konstansban való megadása: \\) • mode : ez is egy string, amely a file elérését és típusát határozza meg. Számítástechnika Tanszék
7. Adatállományok kezelése • A file megnyitása, a mode string • Szöveges file Bináris file • ”r”, ”rt” "rb” Létező file megnyitása olvasásra • ”w”, wt” ”wb” Új file megnyitása írásra. • Ha a file már létezik, akkor a tartalma elvész. • ”a”, ”at” ”ar” A file megnyitása a file végéhez való hozzáírásra. Ha a file nem létezik, akkor a file létrejön. • ”r+”, ”a+t” ”r+b” Létező file megnyitása írásra és olvasásra. • ”w+”, ”w+t” ”w+r” Új file megnyitása írásra és olvasásra (update). Ha a file már létezik, tartalma elvész. • ”a+”, ”a+t” ”a+r” A file megnyitása a file végén végzett írásra és olvasásra (update). • Ha a file nem létezik, akkor létrejön. Számítástechnika Tanszék
7. Adatállományok kezelése • A file megnyitása • Az fopen függvény visszatérési értéke FILE * típusú mutató, • amely sikeres megnyitás esetén kijelöli a filehoz tartozó FILE struktúrát a memóriában, s ezután következhetnek a file kezelés lépései. • Sikertelen file nyitás esetén az fopen függvény NULL pointert ad vissza: • FILE *f1; • f1 = fopen (”C:\\MUNKA\\ADAT1.DAT”, ”rt”); • if (f1 == NULL) • { • printf (”\nSikertelen file nyitási kísérlet ”); • exit (0); • } Számítástechnika Tanszék
7. Adatállományok kezelése • A file lezárása • A használat végén fclose függvény hívással le kell zárnunk az írásra és/vagy olvasásra megnyitott fileokat. A file lezárásakor a memóriában a filehoz tartozó pufferek és más területek automatikus felszabadítása is megtörténik. • Ha az állományon írási műveletet hajtottunk végre, akkor zárás előtt a memóriában található átmeneti pufferek tartalmát célszerű a fileba írni. • FILE *f1; • .... • fflush (f1); • fclose (f1); Számítástechnika Tanszék
7. Adatállományok kezelése • A file végének vizsgálata • A file olvasásakor az feof függvény 1 értéke jelzi a file vége esemény bekövetkezését. • int feof (FILE *f); • A file vége figyelést általában while ciklusban végezzük. • while (! feof (f1)) • { • fscanf (f1, ......); // olvasás a fileból • } • close (f1); Számítástechnika Tanszék
7. Adatállományok kezelése • Pozicionálás a fileban • A file elejére a rewind függvénnyel pozícionálhatunk: • rewind (f1); • Tetszőleges pozíció kiválasztása az fseek függvénnyel történhet: • int fseek (FILE -stream, long offset, int honnan); • ahol • offset a file pozíció relatív távolsága a honnan paraméter által kijelölt pozícióhoz képest. • a honnan paraméter lehetséges értékei: • SEEK-CUR az aktuális pozícióhoz képest • SEEK-END a file végéhez képest • SEEK-SET a file elejéhez képest. • Az aktuális pozíció lekérdezhető az ftell függvénnyel: • long ftell (FILE *stream); Számítástechnika Tanszék
7. Adatállományok kezelése • Hibakezelés • A hibák kezelésére az alábbi függvényeket használhatjuk: • feof (fp) 0 a visszatérési érték, ha elértük a file végét • (ez nem mindig jelent hibát !) • ferror (fp) 0 a visszatérési érték, ha az utolsó file művelet során • hiba volt. • (A stream hiba-jelző adatát teszteli.) • clearerror (fp) • alaphelyzetbe állítja a stream hiba- és file-vége jelzőjét. Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • A megnyitott szöveges adatállományok írására és olvasására az alábbi függvényeket használhatjuk: • Karakter írása és olvasása: int fputc (int c, FILE *stream); • int fgetc (FILE *stream); • String írása és olvasása int fputs (const char *s, FILE *stream); • char * fgets (char *s, int n, FILE *stream); • Formázott adatok írása és olvasása: • int fprintf (FILE *stream, const char *format, ...); • int fscanf (FILE *stream, const char *format, ...); Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • String írása és olvasása: • 7.1. feladat • Olvassa be a billentyűzetről, majd soronként írja egy szöveges állományba az egyik kedvenc versének első versszakát. • Olvassa vissza a fileból a szöveget és írassa a képernyőre soronként. • Számolja meg, hogy egy input adatként bekért magánhangzó hányszor fordul elő a szövegben. Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.1. feladat • void main (void) • { • FILE *ft; • char puffer [80]; • int i=1; • char ch, mgh; • clrscr (); • if ((ft = fopen ("C:\\MUNKA\\vers.txt","w+")) == NULL) • { //megnyitás: írás+olvasás • printf ("\nNem sikerült megnyitni a C:\MUNKA\vers.txt állományt"); • exit (-1); • } Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.1. feladat • printf ("\nKérem a szöveget soronként, * végjelig."); • do • { • printf ("\nAz %2d. sor:",i); gets (puffer); • if (puffer [0] != '*') • { • strcat (puffer, "\n"); • fputs (puffer, ft); • } • i++; • } • while (puffer [0] != '*'); • fflush (ft); Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.1. feladat • clrscr (); • rewind (ft); //pozicionálás a file elejére !! • i=0; • printf ("\nA letárolt szöveg:\n"); • fgets (puffer, 80, ft); • while (!feof (ft)) • { • i++; • printf ("%d. sor: %s",i, puffer); • fgets (puffer, 80, ft); • } Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.1. feladat • rewind (ft); //pozicionálás a file elejére újra • i=0; • printf ("\nMelyik magánhangzót keressük:\n"); • fflush (stdin); • mgh = getche (); • ch = fgetc (ft); //olvasás a fileból karakterenként • while (!feof(ft)) • { • if (ch == mgh) • i++; • ch = fgetc (ft); • } • printf ("\nA szövegben %d db '%c' karakter van",i,mgh); Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.1. feladat • fclose (ft); //a file lezárása • getch (); • } Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • Formázott adatok írása és olvasása: • 7.2. feladat • Olvassa be billentyűzetről és írja text fileba egy tanulócsoport tagjairól az alábbi adatokat:Név, 3 db zh pontszáma. • Készítsen listát a felvitt adatokról. • Számítsa ki külön az első, a második és a harmadik zh átlagát. Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.2. feladat • //1. • struct csopzh • { • char nev [21]; • int zh [3]; • }; • void main (void) • { • //2. • void felvitel (char *); • int lista (char *); • int atlagok (char *, float[]); Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.2. feladat • //3. • char filenev [] = "C:\\munka\\zh2002.txt" ; • int i, menu = 1; • float atlag [3]; • //4. • do • { • clrscr (); • switch (menu) • { • case 1 : felvitel (filenev); break; Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.2. feladat • case 1 : felvitel (filenev); break; • case 2 : if (!lista (filenev)) • printf ("\nNem sikerült megnyitni a %s állományt",filenev); • break; • case 3 : if (!atlagok (filenev, atlag)) • printf ("\nNem sikerült megnyitni a %s állományt",filenev); • else • for (i=0;i<3;i++) • printf ("\nAz %d. zh átlaga:%8.2f",i+1, atlag [i]); • break; • } Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.2. feladat • //5. • getch (); • clrscr (); • printf ("\n1 Felvitel"); • printf ("\n2 Lista"); • printf ("\n3 Átlagok"); • printf ("\nBármely más billentyűre: vége\n"); • printf ("\n\nKérem, válasszon !"); fflush (stdin); • menu = getche ()-48; • } • while (menu >1 && menu < 4); • printf ("\nKöszönöm az együttműködést !\n\nVÉGE"); Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.2. feladat • //6. • void felvitel (char *fn) • { • FILE *ft; • struct csopzh csoport; • int i; • if ((ft = fopen (fn,"w")) == NULL) //megnyitás: írásra • return; Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.2. feladat • do • { • printf ("\nKérem az egytagú nevet(*, ha nincs több):"); • fflush (stdin); gets (csoport.nev); • if (csoport.nev[0] == '*') continue; • printf ("\nKérem a három pontszámot vesszővel elválasztva:"); • fflush (stdin); • scanf ("%d,%d,%d",&csoport.zh[0],&csoport.zh[1],&csoport.zh[2]); • fprintf (ft, "%s\n", csoport.nev); • for (i=0;i<3;i++) • fprintf (ft, "%3d\n",csoport.zh[i]); • } • while (csoport.nev[0] != '*'); Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.2. feladat • //9. puffer ürítés, majd file zárás... • fflush (ft); • fclose (ft); • } Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.2. feladat • //10. • int lista (char *fn) • { • FILE *ft; • struct csopzh cs; • int i; • if ((ft = fopen (fn,"r")) == NULL) • return 0; • printf ("\nL I S T A\nNév zh1 zh2 zh3"); Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.2. feladat • //11. • fscanf (ft, "%s", cs.nev); • while (!feof (ft)) • { • for (i=0; i<3; i++) • fscanf (ft, "%d",&cs.zh[i]); • printf ("\n%-20s%5d%5d%5d",cs.nev, cs.zh[0],cs.zh[1],cs.zh[2]); • fscanf (ft, "%s", cs.nev); • } • printf ("\n\nBillentyűre vár ..."); getch (); • fclose (ft); • return 1; • } Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.2. feladat • //13. • int atlagok (char *fn, float atl[]) • { • FILE *ft; • struct csopzh cs; • int i, db=0; //db:meg kell számolni, mennyien vannak a hallgatók • //14. • if ((ft = fopen (fn,"r")) == NULL) • return 0; • printf ("\nÁ T L A G O K számítása\n"); • for (i=0;i<3;i++) • atl[i] = 0; Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.2. feladat • fscanf (ft, "%s", cs.nev); • //Miért kell... • while (!feof (ft)) • { • for (i=0; i<3; i++) • { • fscanf (ft, "%d",&cs.zh[i]); • atl [i] += cs.zh [i]; • } • db++; • fscanf (ft, "%s", cs.nev); • } Számítástechnika Tanszék
7.1. Szöveges állományok kezelése • 7.2. feladat • //15. • for (i=0;i<3;i++) • atl [i] = atl [i]/db; • printf ("\n\nBillentyűre vár ..."); getch (); • fclose (ft); • return 1; • } Számítástechnika Tanszék
7.2. Bináris állományok kezelése • A bináris állományok kezelése byteonként, vagy blokkonként végezhető el. • A byteos kezeléshez az fgetc és az fputc függvények adnak lehetőséget. • A memóriablokkok fileba írása az fwrite, fileból visszaolvasása az fread függvénnyel végezhető: • size_t fread (void *ptr, size_t size, size_t n, FILE *stream); • size_t fwrite (const void *ptr, size_t size, size_t n, FILE *stream); • Mindkét függvény adott size méretű adat-elemekkel dolgozik, ezekből n darabot ír ki vagy olvas be a függvényhívás során. • A függvények visszatérési értéke a ténylegesen kiírt vagy a visszaolvasott elemek (nem byteok!) számát adja meg. • Mivel a C-ben nem létezik a rekordos file fogalma, ezért a rekordok írására és olvasására is a fenti függvényeket használjuk. Számítástechnika Tanszék
7.2. Bináris állományok kezelése • 7.3. feladat • Olvassa be billentyűzetről és írja bináris fileba egy tanulócsoport tagjairól az alábbi adatokat: • Név, 3 db zh pontszáma. • Készítsen listát a felvitt adatokról. • Számítsa ki külön az első, a második és a harmadik zh átlagát. Számítástechnika Tanszék
7.2. Bináris állományok kezelése • 7.3. feladat • //1. • typedef struct csopzh { • char nev [21]; • int zh [3]; • } cszh; • void main (void) • { • //2. • void felvitel (char *); • int lista (char *); • int atlagok (char *, float[]); Számítástechnika Tanszék
7.2. Bináris állományok kezelése • 7.3. feladat • //3. • char filenev [] = "C:\\munka\\zh2002.dat" ; • int i, menu = 1; • float atlag [3]; • //4. • do • { • clrscr (); • switch (menu) • { • case 1 : felvitel (filenev); break; Számítástechnika Tanszék
7.2. Bináris állományok kezelése • 7.3. feladat • switch (menu) • { • case 1 : felvitel (filenev); break; • case 2 : if (!lista (filenev)) • printf ("\nNem sikerült megnyitni a %s \ állományt",filenev); • break; • case 3 : if (!atlagok (filenev, atlag)) • printf ("\nNem sikerült megnyitni a %s \ állományt",filenev); • else • for (i=0;i<3;i++) • printf ("\nAz %d. zh átlaga:%8.2f",i+1, atlag [i]); • break; • } Számítástechnika Tanszék
7.2. Bináris állományok kezelése • 7.3. feladat • //6. • void felvitel (char *fn) • { • FILE *fb; • cszh csoport; • int i, rsz; • if ((fb = fopen (fn,"w+b")) == NULL) • //megnyitás: írásra • return; Számítástechnika Tanszék
7.2. Bináris állományok kezelése • 7.3. feladat • //7. • do • { • printf ("\nKérem az egytagú nevet(*, ha nincs több):"); • fflush (stdin); gets (csoport.nev); • if (csoport.nev[0] == '*') • continue; • printf ("\nKérem a három pontszámot vesszővel elválasztva:"); • fflush (stdin); • scanf ("%d,%d,%d",&csoport.zh[0],&csoport.zh[1],&csoport.zh[2]); • rsz = fwrite (&csoport, sizeof (cszh), 1, fb); • } • while (csoport.nev[0] != '*'); Számítástechnika Tanszék
7.2. Bináris állományok kezelése • 7.3. feladat • //9. puffer ürítés, majd file zárás... • fflush (fb); • fclose (fb); • } Számítástechnika Tanszék
7.2. Bináris állományok kezelése • 7.3. feladat • //10. • int lista (char *fn) • { • FILE *fb; • cszh cs; • int i, rsz = 1 ; • if ((fb = fopen (fn,"r+b")) == NULL) • return 0; • printf ("\nL I S T A\nNév zh1 zh2 zh3"); Számítástechnika Tanszék
7.2. Bináris állományok kezelése • 7.3. feladat • while (rsz) • { • rsz = fread(&cs, sizeof (cszh), 1, fb); • if (rsz) • printf ("\n%-20s%5d%5d%5d",cs.nev, cs.zh[0],cs.zh[1],cs.zh[2]); • } • printf ("\n\nBillentyűre vár ..."); getch (); • //12. • fclose (fb); • return 1; • } Számítástechnika Tanszék
7.2. Bináris állományok kezelése • 7.3. feladat • //13. • int atlagok (char *fn, float atl[]) • { • FILE *fb; • cszh cs; • int i, db=0; //db:meg kell számolni, mennyien vannak a hallgatók • int rsz = 1; • if ((fb = fopen (fn,"r+b")) == NULL) • return 0; • printf ("\nÁ T L A G O K számítása\n"); • for (i=0;i<3;i++) • atl[i] = 0; Számítástechnika Tanszék
7.2. Bináris állományok kezelése • 7.3. feladat • while (rsz) • { • rsz = fread(&cs, sizeof (cszh), 1, fb); • if (!rsz) break; • for (i=0; i<3; i++) • atl [i] += cs.zh [i]; • db++; • } • for (i=0;i<3;i++) atl [i] = atl [i]/db; • printf ("\n\nBillentyűre vár ..."); getch (); • fclose (fb); • return 1; • } Számítástechnika Tanszék
Adatállományok - teszt • 1. A szöveges állomány is feldolgozható, mint bináris file. • 2. A file megnyitása után következik a file-t azonosító mutató definiálása • 3. A megnyitáskor a file típusát (szöveges vagy bináris) kell csak megadni • 4. A bináris állományok kezelése byteonként, vagy blokkonként végezhető • 5. A C-ben nem létezik a rekordos file fogalma. Számítástechnika Tanszék
Adatállományok - teszt • 1. A szöveges állomány is feldolgozható, mint bináris file. • 2. A file megnyitása után következik a file-t azonosító mutató definiálása • 3. A megnyitáskor a file típusát (szöveges vagy bináris) kell csak megadni • 4. A bináris állományok kezelése byteonként, vagy blokkonként végezhető • 5. A C-ben nem létezik a rekordos file fogalma. Számítástechnika Tanszék