programskijezik c file ui

24
Algoritmi i programiranje Programski jezik C Programski jezik C Elektronski fakultet u Nišu

Upload: aleksandar-stankovic

Post on 17-Nov-2015

20 views

Category:

Documents


2 download

DESCRIPTION

ProgramskiJezikC file UI nisElektronski fakultet copyright Nis, AIP programiranje Ulazno izlazni falj FILE FOR CHAR STRING

TRANSCRIPT

  • Algoritmi i programiranjeProgramski jezik CElektronski fakultet u Niu

    Algoritmi i programiranjeElektronski fakultet u Niu

    Ulaz, izlaz i datoteke/fajloviProgrami itaju podatke sa spoljanjih ureaja i ispisuju podatke na druge spoljanje ureajeprintf i scanf piu/itaju na ekran tj sa tastature prolazni ulaz/izlaz (UI).Trajni UI omoguavaju datoteke (drugi naziv: fajlovi)Standardni C UI operacije ne smatra svojim delomPostoje mnoge razlike: operativni sistem, podrka UI, i sl.Postoje biblioteke sa funkcijama i makroima za UI Bibliteka C funkcija za UI:UI na nivou toka (vii nivo) skrivaju se detalji fizikih ureaja, laka prenosivost na druga radna okruenja Baferovanje se vri automatskiUI na sistemskom nivou (nii nivo)Blisko vezan sa detaljima konkretne implementacijeZa baferovanje ste odgovorni sami

    Algoritmi i programiranjeElektronski fakultet u Niu

    UI na nivou tokaStandardni tok (stream)Model toka je izveden iz UNIX radnog okruenjaC standard prepoznaje oba tipa tokova tekstualni i binarni tokUNIX-ov model i DOS-ov model standardnih tokovaUNIX-ov modelTri standardna toka:stdin standardni ulaz; stdout standardni izlaz;stderr standardni tok za greke;DOS-ov modelTri standardna toka:stdin, stdout, stderrJo dva dodatna:stdprn standardni prikljuak na tampa;stdaux standardni prikljuak za serijsku komunikaciju;

    Algoritmi i programiranjeElektronski fakultet u Niu

    UI na nivou toka (2)stdinStandardno se vezuje za tastaturuBaferuje u redove, to znai da proces ne prima nita do pritiska na taster EnterstdoutStandardno, korisnikov ekranNebaferovan, da bi se izbeglo zadravanje poruka o grekama u baferu

    Algoritmi i programiranjeElektronski fakultet u Niu

    FajloviFajl ili datoteka je skup bajtova kome je dodeljeno neko imeuvaju se na nekom spoljnjem ureaju (disk, traka i sl)Trajnije uvanje, Brz i lak pristup podacimaTekstualni i binarni fajloviRazlika kod DOSa i UNIXa kod oznaavanja oznake kraja tektuslanog fajlaPreusmeravanje ulaza i izlaza (DOS, UNIX): imefajla DOScopy con: imefajla

    Algoritmi i programiranjeElektronski fakultet u Niu

    UI orijentisan na fajlove u C-uDa bi ste koristili spoljanji fajl u C programu, morate mu pridruiti neki tokOvo podrazmeva deklarisanje promenjlive zvane pokaziva na fajl, i davanje vrednosti toj promenljivojVrednost koja se dodeljuje dobija se pozivom funkcije koja pokuava da otvori specificirani fajlGledano sa strane korisnika, fajl ima ime i verovatno neki sadrajSa strane programa, fajl je tok bajtova kome se pristupa preko pokazivaa na fajl Svim operacijama koje pristupaju sadraju fajla ili koje obavljaju odreene operacije nad fajlovima pristupa se preko pokazivaa na fajl.

    Algoritmi i programiranjeElektronski fakultet u Niu

    Standardna biblioteka funkcija za UI: stdio.hSadri tipove i funkcije za UI sa fajlovima Ako treba da ih koristite, obavezno ukljuite

    #include

    Tipovi Pointer na fajl

    FILE *fp;

    ta je tip "FILE *"? Praktino, ne morate da znate dovoljno je da razmiljate o njemu kao apstraktnom tipu podataka kome pristupate preko C funkcija iz biblioteke. Napomena: FILE predstavlja neku strukturu koja sadri informacije o fajlu. Pri tome se mora koristiti pointer FILE *, poto neke funkcije menjaju sadraj nekih elemenata strukture

    FunkcijeRad sa fajlovima (itanje ili upis) zahteva tri koraka: Otvaranje datoteke (pristup). itanje ili upis. Zatvaranje datoteke.

    Nadalje su opisane funkcije za sva tri navedena koraka.

    Algoritmi i programiranjeElektronski fakultet u Niu

    stdio.h Predefinsani tokovi, tipovi i vrednostiFILE tip podataka (struktura) koja uva sve informacije o fajlu, koje se koriste napr kod otvaranja fajla.. FILE *stdin stdin je povezan sa tokom za standardni ulaz za podatke . FILE *stdout stdout je povezan sa standardnim tokom koji se koristi za izlaz iz programa. FILE *stderr stderr je povezan sa tokom za greke. EOF vrednost koja oznaava kraj fajla (end-of-file); Za ANSI C to je negativni celobrojna konstanta, ija je vrednost tradicionalno i uglavnom -1. NULL vrednost nultog pointera (konstanta 0) BUFSIZ celobrojna konstanta (int) koja specificira odgovarajuu veliinu bafera preko kojih ide UI za fajlove. size_t unsigned tip podataka ija je veliina takva da moe da sauva bilo koju vrednost koju moe da vrati sizeof

    Algoritmi i programiranjeElektronski fakultet u Niu

    stdio.h Predefinsani tokovi, tipovi i vrednosti (2)Primer: Korienje standarnih tokovaStandardni ulazni tok koristite kada navodite scanf(), odnosno

    scanf("%d", &val); je ekvivalentno sa sledeim korienjem fscanf(): fscanf(stdin, "%d", &val); Standardni izlazni tok je obaj koji koritite kod printf(), odnosno:

    printf(Vrednost = %d\n", val): je ekvivalentno sa sledeim korienjem fprintf(): fprintf(stdout, Vrednost = %d\n", val): Napomena: standardni ulazni tok je povezan sa tastaturom, a standardni izlazni tok sa ekranom, osim ako nije uraena redirekcija! Standardni tok za greke omoguava da na njega aljete greke: fprintf(stderr, Ne mogu da otvorim ulazni fajl in.list!\n");

    Ovaj tok je asociran sa standardnim izlaznim tokom. Meutim, ako ste uradili redirekciju za izlazni tok, to ne vai za tok za greke!

    Algoritmi i programiranjeElektronski fakultet u Niu

    stdio.h Otvaranje fajla (pristup) Za otvaranje fajlova mogu se koristiti dve funkcijefopen freopen

    Korienje fopen

    fp = fopen(imefajla, mod);

    Gde je: imefajla je string koji sadri ime fajla na disku (ukljuujui i putanju). mod je string koji predstavlja nain otvaranja/pristupa fajlu. Uglavnom ete koristiti fajlove za itanje "r" ili upis "w". fopen() vraa FILE * koji se koristi za pristup fajlu. Ako fajl ne moe da se otvori iz nekog razloga (privilegije, fajl ne postoji i sl), fopen() vraa NULL. Postoje i drugi modovi za pristup, napr. za nadovezivanje (append) ("a") na kraj fajla bez gubitka prethodno sauvanih informacija u fajluZa pristup i za itanje i za pisanje i sl.

    Algoritmi i programiranjeElektronski fakultet u Niu

    stdio.h Otvaranje fajla (pristup) (2)FILE *fopen(const char *path, const char *mode) fopen otvara fajl sa navedenim imenom (string *path koji sadri pored imena i putanju do fajla), i asocira ga sa odgovarajuim tokom (stream). mode je string koji moe da ima sledee vrednosti: r otvara postojei fajl za itanje, poinje od poetka fajla. w kreira novi fajl (ako ne postoji) ili brie sadraj postojeeg i otvara ga za upis, od poetka fajla. a otvara ili kreira fajl za dodavanje na kraj tekstualnog fajla. r+ - otvara fajl za itanje i upis, poev od startne pozicije (auriranje). w+ - isto kao w, s tim da se fajl otvara za itanje i upis (auriranje). a+ - isto kao a, s tim da se fajl otvara za itanje i upis (auriranje). String mode moe da sadri i b kao drugi ili trei karakter, da oznai da se radio binarnom fajlu. String mode moe da sadri i druge karaktere koji se mogu koristiti u procesu implementacije. Ako se fajl otvara za auriranje (mod +), operacija izlaza (upisa) ne moe da sledi iza operacije ulaza (ittanje) bez operacije flushing-a za bafer (fflush())) ili repozicioniranja (fseek(), fsetpos, rewind); takoe, operacija itanja ne moe da sledi iza operacije upisa bez flush-inga bafera ili repozicioniranja osim ako ste dostigli kraj fajla. Ako je fopen uspeno otvorio fajl, vraa pointer na FILE. Inae vraa NULL i setuje se errno.

    Algoritmi i programiranjeElektronski fakultet u Niu

    stdio.h Otvaranje fajla (pristup) (3)FILE *freopen(const char *pathname, const char *mode, FILE *stream) freopen radi kao fopen s tim da asocira fajl sa nekim tokom, umesto da kreira novi tok. freopen se koristi primarno da se fajl asocira sa nekim standardnim tokom za tekstualne podatke (stdin, stdout, ili stderr).

    Primer:FILE *ifp, *ofp; char *mode = "r"; char outputFilename[] = "out.list"; ifp = fopen("in.list", mode); if (ifp == NULL) { fprintf(stderr, Ne mogu da otvorim ulazni fajl in.list!\n"); exit(1); } ofp = fopen(outputFilename, "w"); if (ofp == NULL) { fprintf(stderr, " Ne mogu da otvorim izlazni fajl %s!\n", outputFilename); exit(1); } Napomena: Fajl koji otvarate za itanje ("r") mora da postoji. Kod upisa ("w"), ako pokuate da otvorite fajl koji ne postoji, kreirae se novi sa zadatim imenom. Ako postoji takav fajl, njegov kompletan sadraj e biti obrisan!!

    Algoritmi i programiranjeElektronski fakultet u Niu

    stdio.h itanje i upisNakon uspenog otvaranja fajla moete da:itate sadraj korienjem

    fscanf() upisujete vrednosti korienjem

    fprintf(). Ove funkcije rade na isti nain kao scanf() i printf(), osim to zahtevaju dodatni parametar FILE * koji specificira fajl u koji piete ili iz koga itate podatke. Postoje druge funkcije u stdio.h za upis i itanje! Pogledajte ref.uputstvo!

    Dostizanje kraja fajla: Funkcija fscanf(), kao i scanf(), noramlno vraa broj vrednosti koje moe da proita. Ako doe do kraja fajla, vraa specijalnu vrednost EOF. Obrada celog fajla moe da ide u petlji, gde je uslov za izlazak da li ste doli do EOFNeodostatak: ta ako doe do greke u formatu podataka, pa se umesto oekivanog slova proita broj. Tada fscanf() ne moe da proita tu liniju i samim tim ne prelazi na sledeu u ovom sluaju fscanf() nee vratiti EOF.... Ovakve greke prouzrokuju probleme tipa kako proitati ostatak fajla ili mogu da prouzrokuju beskonane petlje.

    Algoritmi i programiranjeElektronski fakultet u Niu

    stdio.h itanje i upis (2)Primer: itanje iz fajla Proitati iz datoteke imena studenata (max. duine 8) i rezultat sa ispita i poveati rezultat svakog za 10 poenaDatoteka:in.list------ Pera 70 MIka 98 Aca A+... Reenje (deo koda):char ime[9]; /* Ime plus oznaka kraja stringa */ int rezultat; ... while (fscanf(ifp, "%s %d", ime, &rezultat) != EOF) { fprintf(ofp, "%s %d\n", ime, rezultat+10); } ... Jedno reenje problema kod itanja podataka pogrenog formata je testiranje broja vrednosti koje treba da proitamo sa fscanf(). Poto je navedeno format (u primeru) "%s %d", oekuje se itanje dve vrednost tipa bi uslov provere bio:

    while (fscanf(ifp, "%s %d", ime, &rezultat) == 2)

    Algoritmi i programiranjeElektronski fakultet u Niu

    stdio.h itanje i upis (2)Drugi nain: korienje funkcije feof() iz biblioteke stdio.h. feof() kao argument ima pointer na fajl a vraa true/false u zavisnosti od toga da li smo dostigli kraj fajla.

    Primer korienja: while (!feof(ifp)) { if (fscanf(ifp, "%s %d", ime, &rezultat) != 2) break; fprintf(ofp, "%s %d", ime, rezultat+10); } Napomena:Kao i kod testiranja != EOF, ova funkcija moe prouzrokovati beskonanu petlju ako je format ulaznog podatka iz fajla neodgovarajui. Moe se dodati i kod za proveru da li su proitane dve vrednosti.

    Algoritmi i programiranjeElektronski fakultet u Niu

    stdio.h Spisak funkcija za itanje i upis (1)itanje karaktera iz fajla - getc, fgetc i getcharint fgetc(FILE *stream) ita sledei karakter iz ulaznog toka i vraa ga kao int (kod karaktera)int getc(FILE *stream) Radi kao fgetc s tim da je obino implementiran kao makroint getchar(void) ita sledei kakarkter sa stdin; obino implementiran kao getc(stdin) (to znai kao getc, tj kao makro)

    Upis karaktera u fajl - putc, fputc i putcharint fputc(int c, FILE *stream) Upisuje c na izlazni tok (stream) kao unsigned char i vraa karakter kao int. Ako doe do greke, vraa se EOF i setuje se errno. int putc(int c, FILE *stream) Identina kao fputc ali implemetirana kao makroint putchar(int c) Upisuje c na stdout, implementirana kao putc(stdout) (makro)

    Algoritmi i programiranjeElektronski fakultet u Niu

    stdio.h Spisak funkcija za itanje i upis (2)itanje stringa iz fajla - fgets i getschar *fgets(char *s, int n, FILE *stream) ita karaktere iz toka stream i smeta ih u string na koji ukazuje s. itanje se prekida kod newline karaktera, dostizanja kraja fajla (end-of-file) ili je proitano n-1 karaktera, i oznaka kraja stringa '\0' je dodata stringu s (nakon svakog newline karaktera) Ako je dostignut kraj fajla, bez proitanog karaktera, fgets vraa NULL i sadraj stringa s ostaje nepromenjen. Ako doe do greke tokom itanja, vraa NULL i sadraj stringa s je nedefinisan. Inae, vraa s (pointer na proitani string)char *gets(char *s, FILE *stream) Slino kao fgets, ali mnogo opasniji !! Ne pamti newline karakter Vano: gets podrazumeva da je s neodreeno velik string, to moe da izazove dosta problema (svesno ili nesvesno).

    Algoritmi i programiranjeElektronski fakultet u Niu

    stdio.h Spisak funkcija za itanje i upis (3)Upis stringa u fajl - fputs i putsint fputs(const char *s, FILE *stream) Upisuje null-terminated string s na izlazni tok stream. Ako doe do greke, vraa EOF. Inae vraa ne-negativni ceo broj. int puts(const char *s) Upisuje null-terminated string s, iza koga sledi newline karakter, na standardni izlazni tok stdout.

    itanje iz binarne datoteke - freadsize_t fread(void *ptr, size_t siz, size_t num, FILE *stream) ita do najvie num objekata, gde je svaki veliine siz bajtova, sa ulaznog toka stream, i smeta ih u memorijsku lokaciju na koju ukazuje ptr. Vraa broj proitanih objekata. Ako doe do greke vraa nulu. Ako doe do kraja fajla (end-of-file), vrednost koju vrati bie manja od num (moe biti i nula), pri emu se mogu koristiti feof ili ferror da bi se video razlog greke)

    Algoritmi i programiranjeElektronski fakultet u Niu

    stdio.h Spisak funkcija za itanje i upis (4)Upis u binarni fajl - fwritesize_t fwrite(const void *ptr, size_t siz, size_t num, FILE *stream) Upisuje do num objekata, gde je svaki veliine siz bajtova, iz memorijske lokacije na koju ukazuje ptr na izlazni tok stream. Vraa broj upisanih objekata. Ako doe do greke, vraa nulu.

    Upis formatiranog izlaza - printf, fprintf, sprintfint printf(const char *format, ...) Pie na standardni izlazni tok stdout. int fprintf(FILE *stream, const char *format, ...) Pie na izlazni tok stream. int sprintf(const char *str, const char *format, ...) sprintf pie" svoj izlaz u string str (zavren oznakom kraja '\0'.)

    Sve tri funkcije vraaju broj upisanih karaktera (bez '\0' za sprintf)

    itanje formatiranog ulaza - scanf, fscanf, sscanfint scanf(const char *format, ...) int fscanf(FILE *stream, const char *format, ...) int sscanf(const char *str, const char *format, ...)

    Algoritmi i programiranjeElektronski fakultet u Niu

    stdio.h Spisak funkcija za itanje i upis (5)Provera statusa fajla - feof, ferror i clearerrint feof(FILE *stream) Proverava indikator kraja fajla (end-of-file) za navedeni tok stream i vraa broj razliit od nule ako je setovan. Napomena: oznaka kraja fajla se nalazi iza poslednjeg karaktera u fajlu. int ferror(FILE *stream) Proverava indikator greke za tok stream i vraa broj razliit od nula ako je setovan. void clearerr(FILE *stream) Brie vrednosti indikatora za kraj fajla i indikatora za greke za navedeni tok stream. Napomena: kada se jednom setuju ova dva indikatora, oni se ne resetuju sve do poziva clearerr (osim ako se repozicioniranjem ne obrie oznaka kraja fajla tj vrednost odgovarajueg indikatora.)

    Algoritmi i programiranjeElektronski fakultet u Niu

    stdio.h Spisak funkcija za itanje i upis (6)Odreivanje pozicije u fajlu - fgetpos, fsetpos, rewind, fseek, i ftellint fgetpos(FILE *stream, fpos_t *pos); Smeta vrednost tekue pozicije indikatora za tok stream u pos. pos je implementation-defined tip koji moe da ima i kompleksnu strukturu. Ako doe do greke, vraa broj vei od nula i setuje se errno. int fsetpos(FILE *stream, fpos_t *pos) Postavlja indikator pozicije u fajlu za stream na poziciju definisanu u pos. Ako doe do greke, vraa broj vei od nula i setuje se errno. Kod uspenog izvrenja, indikator end-of-file indicator se brie. void rewind(FILE *stream) Postavlja indikator pozicije na poetak fajla. int fseek(FILE *stream, long offset, int whence) Postavlja indikator pozicije za stream. Nova pozicija se odreuje dodavanjem vrednosti pomeraja offset u odnosu na poziciju zadatu u whence: Ako je whence postavljeno na SEEK_CUR, pomeraj se rauna u odnosu na tekuu poziciju u fajlu. Ako je whence postavljeno na SEEK_SET, pomeraj se rauna u odnosu na poetak fajla. Ako je whence postavljeno na SEEK_END, pomeraj se rauna u odnosu na kraj fajla.

    SEEK_CUR, SEEK_SET, i SEEK_END su definisani u . fseek se obino primenjuje na binarne fajlove. long ftell(FILE *stream) Vraa tekuu poziciju u fajlu za stream. Za binarne fajlove, vrednost koju vrati je broj bajtova od poetka fajla do tekue pozicije. Za tekstualne fajlove, vrednost je implementation-defined.

    Algoritmi i programiranjeElektronski fakultet u Niu

    stdio.h Zatvaranje fajla Funkcija za zatvaranje: fclose() int fclose(FILE *stream) Baferovani sadraj se upisuje na disk i zatvara se tok stream. Naknadno korienje istog toka stream bez prethodnog freopen prouzrokuje greku. Ako je operacija zatvaranja uspena, fclose vraa 0. Inae, vraa EOF i postavlja se kod greke u errno.

    Primer (dodatak koda za preth. primer): zatvaranje ulaznog i izlaznog fajla: fclose(ifp); fclose(ofp); Napomena: Fajl mora biti zatvoren nakon korienja!

    Zatvaranje fajla je veoma vano, naroito za izlazne fajlove !!Razlog je to je izlaz baferovan. Ako hoete da u C-u neto upiete u fajl, napr: fprintf(ofp, Nesto pisem!\n"); ne znai da e se navedeni sadraj upisati u fajl na disku raunara, ve da e taj sadraj zavriti u baferu u memoriji koji se koristi za pristup fajlu! Taj bafer uva tekst privremeno, do zatvaranja fajla.Nakon zatvaranja fajla, sadraj bafera se upisuje na disk.

    Algoritmi i programiranjeElektronski fakultet u Niu

    Primeri: UI sa fajlovimaitanje iz fajla i konverzija malih u velika slova

    #includeint main(int argc, char** argv) { char* imefajla = "upper.c"; FILE* fptr; char c; if (argc > 1) imefajla = argv[1]; fptr = fopen(imefajla,"r"); while((c = getc(fptr)) != EOF) { if (islower(c)) c = toupper(c); printf("%c",c); }} Dvostruki prored#includeint main(int argc, char** argv) { char* ulazni_fajl = "upper.c"; char* izlazni_fajl = "double.txt"; FILE* iptr; FILE* optr; char c; if (argc > 1) ulazni_fajl = argv[1]; if (argc > 2) izlazni_fajl = argv[2]; iptr = fopen(ulazni_fajl,"r"); optr = fopen(izlazni_fajl,"w"); while((c = getc(iptr)) != EOF) { putc(c,optr); if (c == '\n') putc(c,optr); } fclose(iptr); fclose(optr); }

    Algoritmi i programiranjeElektronski fakultet u Niu

    Obrada podataka iz fajla#includeint main() { FILE* iptr; char c; int n1, n2; iptr = fopen("access.dat","r"); while((c = getc(iptr)) != EOF) { switch(c) { case '+': fscanf(iptr,"%d %d",&n1,&n2); printf("process %d arrives, size %d\n",n1,n2); break; case 'r': fscanf(iptr,"%d %d",&n1,&n2); printf("process %d reads page %d\n",n1,n2); break; case 'w': fscanf(iptr,"%d %d",&n1,&n2); printf("process %d reads page %d\n",n1,n2); break; case '-': fscanf(iptr,"%d",&n1); printf("process %d leaves\n",n1); break; } }}