Datoteke predavač: Nadežda Jakšić
svi podaci sa kojima smo do sada radili u programima su smeštani u operativnu memoriju računara i trajali su najduže koliko i sam program; kada program završi sa radom, vrednost svih promenljivih se gubi; ukoliko želimo na nam neki podaci ostanu sačuvani i posle izvršavanja programa moramo da ih smestimo na hard disk, a jedan od načina da to uradimo je da ih sačuvamo u fajl (datoteku) npr. imenik koji ne bi bio praktičan ako bismo pri svakom pokretanju sve podatke ponovo unosili datoteka predstavlja sekvencu bajtova i može biti tekstualna ili binarna za rad sa datotekama u C-u koriste se pokazivači; datoteka je predstavljena posebnim pokazivačem: FILE * fp; //pokazivač se tumači kao memorijska lokacija fajla na disku
fajl se otvara funkcijom fopen koja vraća pokazivač na strukturu FILE sve ostale funkcije za rad sa fajlovima koriste taj pokazivač umesto imena fajla sve funkcije osim fopen vraćaju vrednost int mnoge funkcije za rad sa fajlovima vraćaju konstantu EOF (End Of File) ukoliko nastane greška pri izvršavanju ili ako se dođe do kraja fajla
fopen (imefajla, mod) fclose (f) feof (f) fseek (f, kol, odakle) ftell (f) ferror (f) getc (f) otvaranje fajla zatvaranje fajla (rezultat 0=uspešno, EOF neuspešno) ispitivanje da li se došlo do kraja fajla (rezultat 0=nije kraj, >0 kraj) pozicioniranje SEEK _SET od početka SEEK_CUR od trenutne pozicije SEEK_END od kraja fajla trenutna pozicija u fajlu (vraća int vrednost ili -1 za grešku) spitivanje greške u prethodnoj operaciji (0=nema greške) citanje znaka iz fajla (vraća int ili EOF u slučaju greške)
putc (znak, f) fgetc (f) fputc (znak, f) fgets (f, kol., string) fputs (string, f) fscanf (f,maska,prom.) fprintf (f,maska,prom.) fflush (f) upisivanje znaka u fajl (isti karakter ili EOF u slučaju greške) čitanje znaka iz fajla (isto kao getchar) upisivanje znaka u fajl čitanje stringa iz fajla NULL ako nema više podataka upisivanje stringa u fajl (vraća >0 ili EOF u slučaju greške) čitanje promenljivih iz fajla - vraća broj pročitanih znakova, negativnu vrednost za grešku ili EOF ako nema podataka upisivanje promenljivih u fajl - vraća broj upisanih znakova ili negativnu vrednost u slučaju greške pražnjenje bafera (0=uspešno, EOF neuspešno)
r //otvaranje postojećeg fajla za čitanje podataka w // otvaranje fajla za pisanje, ako ne postoji fajl kreira se novi, ako postoji, pisanje počinje od početka (briše se postojeći sadržaj) a //otvaranje postojećeg fajla za dodavanje sadržaja na postojeći sadržaj r+ //otvaranje postojećeg fajla za čitanje i pisanje w+ //otvaranje fajla za čitanje i pisanje, ukoliko fajl postoji, prvo mu se dužina smanjuje na nulu, ako fajl ne postoji, kreira se novi fajl a+ //otvaranje fajla za čitanje i pisanje, čitanje se vrši od početka fajla, a pisanje u fajl se nastavlja na postojeći sadržaj, ukoliko fajl ne postoji krera se novi "b" //ako se iza slova w, r ili a napiše slovo b to označava da datoteku treba otvoriti u binarnom modu, inače se datoteka otvara u tekstualnom modu (rb, wb, ab, rb+,wb+, ab+ ili r+b, w+b )
po završetku rada sa fajlom potrebno je zatvoriti fajl int fclose (FILE *fp ); pozivom ove funkcije se prazni bafer koji je služio za ispis u fajl (sav zaostali sadržaj se upisuje u fajl), oslobađa se operativna memorija koja je korišćena za obradu fajla; ukoliko funkcija uspešno završi snimanje u fajl vraća se 0, inače se vraća definisana konstanta EOF
#include <stdio.h> #include <conio.h> int main() { FILE *fp; } fp = fopen ("test.txt", "w+"); fprintf (fp, "Ovo je test za funkciju fprintf...\n"); //upisuje u fajl fputs ("Ovo je test za funkciju fputs...\n", fp); //upisuje u fajl fclose (fp); return 0;
#include <stdio.h> int main() { } FILE *fp; char buff[255]; fp=fopen ("test.txt", "r"); fgets (buff, 255, (FILE*)fp); printf ("1: %s\n", buff ); //ispisuje na ekran fgets (buff, 255, (FILE*)fp); printf ("2: %s\n", buff ); //ispisuje na ekran fclose (fp); return 0;
//proverava da li postoji datoteka druga u tekućem folderu, otvori datoteku, ispiše na monitoru i zatvori #include <stdio.h> printf ("Tekstualni sadrzaj datoteke <%s>...\n", #include <stdlib.h> n); int main() { FILE *f; char *n="druga.txt"; char c; f=fopen(n,"r ); while ((c=fgetc(f))!=eof) putchar(c); printf ("\nkraj sadrzaja datoteke <%s>...\n", n); fclose(f); return 0;} if (f== NULL ) //ako pokazivač na datoteku druga.txt ne pokazuje ni { na šta (ima vrednost nula) printf ("Datoteka <%s> nije uspesno otvorena.\n", n); exit(1); } printf ("Datoteka <%s> je uspesno otvorena\n", n);
//program otvara fajl mojfajl.txt za pisanje, upisuje u njega string i zatvara fajl; kod zatvaranja i otvaranja fajla proverava se uspešnost i ispisuje poruka #include <stdio.h> #include <stdlib.h> int main() { FILE *fp; fp = fopen ("mojfajl.txt", "w"); //w ako ne postoji kreira fajl if (fp!=null) {printf ("Fajl je uspesno otvoren.\n"); fputs ("Ispis", fp); } //upisivanje sadržaja u fajl else {printf ("Greska.\n"); } if (fclose(fp)!=eof) {printf ("Fajl je uspesno zatvoren.\n"); exit(0); } else exit(1); return 0; }
demonstrira se formatiran upis 5 realnih brojeva u tekstualnu datoteku korisnik unosi brojeve datoteka ne mora prethodno da se kreira - mod je w funkcija fscanf() je pogodna za formatirani unos brojeva, ali nije pogodna za unos stringova i znakova
#include <stdlib.h> #include <stdio.h> int main() { FILE *fp; float data[5]; int i; char filename[20]; puts("unesi 5 real.brojeva"); for (i = 0; i < 5; i++) scanf ("%f", &data[i]); //pri unosu imena datoteke napisati npr. realni.txt //isprazni mogući višak znakova iz bafera ulaza fflush (stdin); puts("unesi ime datoteke:"); gets (filename); if ((fp = fopen (filename, "w")) == NULL) {fprintf (stderr, "Greska pri otvaranju datoteke %s.", filename); exit(1);} //ispiši vrednosti u datoteku i na standardni izlaz for (i = 0; i < 5; i++) {fprintf (fp, "\n podatak[%d] = %f", i, data[i]); fprintf (stdout, "\n podatak[%d] = %f", i, data[i]);} fclose(fp); printf ("\n Sada procitaj datoteku: %s, nekim editorom",filename); return(0);}
//datoteka ulaz.txt sadrži cele brojeve - izračunati njihov zbir i zapisati u izlaznu datoteku izlaz.txt - kreirati datoteke ulaz i izlaz u tekućem folderu #include <stdio.h> while (fscanf(ul,"%d",&a)!=eof) zbir+=a; #include <stdlib.h> int main() { FILE *ul,*iz; int a,zbir=0; ul=fopen ("ulaz.txt","r"); iz=fopen ("izlaz.txt","w"); if (ul==null) {fprintf (stderr,"neuspesno otvaranje ulaz.txt"); exit (EXIT_FAILURE); } if (iz==null) { fprintf (stderr,"neuspesno otvaranje izlaz.txt"); exit(exit_failure);} fprintf (iz,"%d",zbir); fclose (ul); fclose (iz); return 0; }
//program demonstrira dodavanje sadržaja u datoteku (funkcija append) - svaki put kada se program pokrene na izvršenje dodaje se nov sadržaj u datoteku #include <stdio.h> int main(){ FILE* datoteka; int godina = 2018; if ((datoteka=fopen("druga.txt","a"))==null) //mod je a {fprintf (stderr,"greska: nisam uspeo da otvorim dat.txt\n"); return 1;} fprintf (datoteka,"zdravo svima\n"); fprintf (datoteka,"sve najbolje u %d. godini!!!\n",godina); fclose(datoteka); return 0; }
//odrediti broj redova u tekstualnom faju čije ime unosi korisnik prethodno kreirati datoteku redovi.txt i uneti nekoliko redova teksta #include <stdio.h> #include <stdlib.h> int main() { FILE *ul; int BrRed=0; char ch,ime[100]; printf ("Unesite putanju do fajla:"); scanf ("%s",ime); ul=fopen (ime,"r"); if (ul==null) {fprintf (stderr,"neuspesno otvaranje ulaz.txt"); exit (EXIT_FAILURE);} while ((ch=fgetc(ul))!=eof) if (ch=='\n') BrRed++; printf ("Broj redova je %d.",brred); fclose (ul); return 0;}
//u datoteci automobili.txt nalazi se spisak sa modelima automobila, godištima i cenom - pročitati podatke iz datoteke i na standardnom izlazu ispisati podatke o automobilima čija je cena veća od 10 000 evra #include<stdio.h> #define DIM 100 typedef struct { char model [20]; int godiste; float cena;}auto; int main(){ FILE *ulaz; AUTO nizauto[dim]; int n, i; ulaz=fopen ("automobili.txt", "r"); if (ulaz==null){ printf ("Ulazna datoteka nije dostupna"); return 1; } n=i; for (i=0;i<n;i++) { if(nizauto[i].cena>10000) printf ("%s %d %f\n", nizauto[i].model, nizauto[i].godiste, nizauto[i].cena); } fclose (ulaz); return 0;} i=0; while (!feof (ulaz)) {fscanf (ulaz, "%s %d %f", &nizauto[i].model, &nizauto[i].godiste, &nizauto[i].cena); i++; }
//u datoteci studenti.txt nalaze se podaci o rezultatima ispita: ime i prezime, broj indeksa i broj bodova - pročitati podatke i u datoteku rezultati.txt upisati prvih 30% sortiranih podataka o studentima po broju bodova #include<stdio.h> #define DIM 100 typedef struct { char imeprezime [60]; char brindexa [9]; int bodovi; }STUDENT; void razmeni (STUDENT *a, STUDENT *b) {STUDENT tmp; tmp=*a; *a=*b; *b=tmp;} void sort (STUDENT niz [ ], int n) {int i, j; for (i=0;i<n-1;i++) {for(j=i+1;j<n;j++) {if (niz[i].bodovi<niz[j].bodovi) razmeni(&niz[i], &niz[j]); }}}
int main() {FILE *ulaz; FILE *izlaz; STUDENT niz[dim]; int n, i; float procenat; ulaz=fopen ("studenti.txt", "r"); if (ulaz==null) {printf ("Ulazna datoteka nije dostupna"); return 1;} izlaz=fopen ("rezultati.txt", "w"); if (izlaz==null){ printf ("Izlazna datoteka nije dostupna"); return 1;} i=0; while (!feof (ulaz)) {fscanf (ulaz, "%s%s%d", niz[i].imeprezime, niz[i].brindexa, &niz[i].bodovi); i++;}
n=i; procenat=n*30/(float)100; printf ("\npr %f\n",procenat); sort (niz,n); for (i=0;i<procenat;i++) { fprintf (izlaz,"%s %s %d\n", niz[i].imeprezime, niz[i].brindexa, niz[i].bodovi); printf ("%s %s %d\n", niz[i].imeprezime, niz[i].brindexa, niz[i].bodovi);} fclose (ulaz); fclose (izlaz); return 0; }