7. előadás (2005. április 12.) Láncolt lista File kezelés 1
Láncolt lista 1. Típus definíció: typedef struct elem { char nev[30]; struct elem *kovet; } ELEM; Műveletek: –elem memória foglalása, –elem hozzáfűzése a lánc végéhez, –elem beszúrása egy adott elem után, –elem törlése címe alapján, –elem keresése név szerint. 2
Láncolt lista 2. Elem memória foglalása: ELEM * ujelem() { ELEM *p; if ((p=(ELEM *) malloc(sizeof(ELEM))) == (ELEM *) NULL) { perror("uj elem"); exit(MEMHIBA); } p -> kovet=(ELEM *) NULL; return p; } 3
Láncolt lista 3. Elem hozzáfűzése a lánc végéhez: static ELEM * fej = (ELEM *)NULL; void hozzaad(ELEM *ujelem) {ELEM *p; if (fej == NULL) { fej=ujelem; return; } for (p=fej;p->kovet!=(ELEM *)NULL;p=p->kovet); p->kovet=ujelem; } 4
Láncolt lista 4. Elem beszúrása egy adott elem után: void beszur(ELEM *hova,ELEM *ujelem) { if(hova==(ELEM *)NULL || hova==ujelem || ujelem==(ELEM *)NULL || hova->kovet==ujelem) { printf("\n hibas parameter");return; } ujelem->kovet = hova->kovet; hova->kovet = ujelem; } 5
Láncolt lista 5. Elem törlése címe alapján: void torol(ELEM *torelem) { ELEM *p; if (fej==torelem) fej=torelem->kovet; else { for(p=fej; (p!=(ELEM *)NULL)&&(p->kovet!=torelem); p=p->kovet); 6
Láncolt lista 6. if (p==(ELEM *)NULL) { printf("nincs meg a torlendo elem"); return; } p->kovet = p->kovet->kovet; } free (torelem); } 7
Láncolt lista 7. Elem keresése név szerint: ELEM *keres(char *kernev) { ELEM *p; for (p=fej; p!=(ELEM *)NULL; p=p->kovet) if (strcmp(p->nev,kernev)==0) return p; return (ELEM *)NULL; } Gyakorlásként: rekurzív megfogalmazás, kétszeresen láncolt lista (előző, követő elem). 8
File kezelés A C nyelvben a file byte-ok sorozata: stream. A programozónak kell a tartalmát értelmeznie. Kivétel: a text típusú file '\n' karakter operációs rendszer függő kezelését elrejti előlünk. Buffer: az I/O felgyorsítására használt átmeneti munkaterület. Intelligens vezérlő: a CPU-val párhuzamosan képes a tényleges fizikai I/O műveleteket elvégezni. A buffer mérete alkalmazkodik a fizikai tároló egységhez (disk block). 9
Bufferelési típusok Nincs bufferelés: szinkron olvasás/írás lassú fájlok esetén. Soros aszinkron vonalak kezelése, adatgyűjtő eszközök, egér. Sorbufferelés: a rendszer a karakteres munkaterületet újsor karakter érzékelésénél adja át (terminálok). Blokk bufferelés: a rendszer mindaddig a munkaterületen dolgozik, amíg az be nem telik. A diszk fájlok blokk buffereltek. A szabványos be/kimenetek sor és blokk buffereltek is lehetnek (implementáció függő). 10
File megnyitása 1. FILE előre definiált típusú struktúra: Előre definiált FILE* változók: stdin, stdout, stderr. Megnyitás: FILE* fopen(char* filenev, char* mod); Visszatérő érték: érvényes FILE pointer a fájl azonosítására a későbbi műveletekhez, vagy NULL pointer, ha nem sikerült a megnyitás. filenev : a fájl operációs rendszerbeli azonosítója. 11
File megnyitása 2. A mod értéke 1, 2 vagy 3 karakter: r:csak olvasás (létező fájl) w:csak írás a:csak hozzáírás r+:olvasás+írás (létező fájl) w+:olvasás+írás a+:olvasás+hozzáírás A harmadik karakter: b:bináris, a struktúra mérete határozza meg az átviendő bájtok számát t:text (szöveges), újsor karakterrel határolt részek átvitele 12
File lezárása int fclose(FILE *filepointer); A visszatérő érték: 0ha sikeres volt EOFha nem sikerült 13
Fájl nyitás: példa FILE * inpf;.... if ((inpf = fopen(" ", "rt"))==NULL) { fprintf (stderr,"File nyitási hiba...\n"); exit(1); } else { /* A file feldolgozása*/ } 14
Szöveges file írása, olvasása int fprintf(FILE *f, char *s,...); int fscanf(FILE *f, char *s,...); int getc(FILE *f); /* hiba EOF*/ int putc(int c, FILE *f); /* kiirt kar., hiba EOF*/ int fputs(char *s, FILE *f); /* '\0' nélkül, utoljára kiirt kar., hiba\ EOF*/ char * fgets(char *s, int n, FILE *f); /* sorvége jelig max n-1, '\0'-t beteszi,\ hiba NULL*/ A getc, putc makró bináris fájlnál is használható. 15
Bináris file írása, olvasása size_t fread(void *p,int meret,int n, FILE *f); n darab meret méretű adatot olvas be és elhelyezi a p címtől kezdődően. Visszatérési érték: a beolvasott adatok száma, hiba vagy EOF esetén ez n -től kisebb. size_t fwrite(void *p,int meret,int n, FILE *f); 16
Pozícionálás fájlban 1. Minden fájlhoz tartozik egy bájtokban számított aktuális pozíció. Értéke megnyitáskor: 0. Az I/O műveletek automatikusan állítják. Állítása programból: long fseek (FILE *f,long eltolas,int bazis); Előjelesen hozzáadja a bazis -hoz az eltolas értékét és ez lesz az új pozíció. bazis előredefiníált értékei: SEEK_SET :a file eleje SEEK_CUR :az aktuális pozíció SEEK_END :a file vége Visszatérő érték: 0, ha sikeres, nem 0 egyébként. 17
Pozícionálás fájlban 2. Az aktuális file pozíció lekérdezése: long ftell (FILE *f); Visszatérő érték: a fájl elejétől számított pozíció, vagy sikertelenség esetén -1. A fájl elejére állás: void rewind (FILE *f); A buffer kiürítése: int fflush (FILE *f); /*0 vagy EOF*/ A file pozíció állítása a buffer kiírását is jelenti, ha az nem a bufferen belül van. 18