06.april: Datoteke - nastavak
Gradivo o kojem je reč:
Prezentacija koja se koristi na času:
ako ne možete da vidite prezentaciju, kliknite na LINK
Pozicioniranje unutar datoteke *(7.4 u knjizi)
Često postoji potreba da se program pozicionira na drugu lokaciju u datoteci. Ovaj mehanizam je prisutan još iz doba kada su datoteke bile smeštane na magnetnim trakama, pa prema tome i funkcije imaju sličan naziv, odnosno fseek() i rewind(), što bi na našem jeziku značilo „premotati”. Premotavanje može da bude unapred ili unazad. Referentne tačke mogu da budu od početka datoteke, od trenutne pozicije, ili od kraja datoteke. Postoji i funkcija ftell() koja govori trenutnu poziciju unutar datoteke. Funkcija rewind() „premotava” datoteku na njen početak.
int fseek(FILE* f, long pomeraj, int reper)
Ova funkcija vrši podešavanje pozicije u fajlu, tako da se narednim čitanjem ili pisanjem pristupa podacima na početku nove pozicije. Pozicioniranje u datoteci (fajlu) f se vrši na mesto čija je udaljenost pomeraj bajtova od označene reperne tačke reper. Moguće reperne tačke obeležavaju se simboličkim konstantama SEEK_SET (početak fajla/datoteke), SEEK_CUR (trenutna pozicija u datoteci), ili SEEK_END (kraj datoteke).
Ako je sve urađeno kako treba, funkcija vraća nulu. Nenulta vrednost funkcije označava grešku.
Funkcija fseek obavezno mora da se pozove pre prvog čitanja, posle nekoliko upisivanja, odnosno pre prvog upisivanja posle nekoliko čitanja. Na primer, kada se u toku ažuriranja sadržaja datoteke, posle prepisivanja preko starog sadržaja zapisa želi pročitati prvi sledeći zapis, funkcija fseek mora da se pozove, bez obzira što se već nalazi na ispravnoj poziciji unutar datoteke.
Primer: pozicioniranje na 10000-ti bajt datoteke:
greska = fseek(datoteka, 10000L, SEEK_SET) != NULL;
long ftell(FILE *f)
Ova funkcija nalazi trenutnu poziciju unutar datoteke/fajla f. Vrednost funkcije je trenutna pozicija u bajtovima u odnosu na početak datoteke, odnosno -1L u slučaju greške.
Primer: Nalaženje trenutne pozicije u datoteci
greska = (mesto = ftell(datoteka)) == -1L;
Primer fajla (C fajl) u kojem se demonstrira pozicioniranje unutar datoteke
VAŽNO: Funkcija ftell uzima kao argument pokazivač na otvorenu datoteku i vraća trenutni položaj unutar datoteke. Kod binarnih datoteka ta je broj znakova koji prethode trenutnom položaju unutar datoteke, dok je kod tekstualnih datoteka ta veličina ovisna o implementaciji! U svakom slučaju, izlaz iz funkcije ftell mora dati dobar drugi argument za funkciju fseek.
Formatirani ulaz i izlaz *(7.2.2 u knjizi)
(funkcije fcanf() i fprintf() )
Za formatirani upis odnosno očitavanje podataka iz datoteka mogu se koristiti funkcije fscanf() i fprintf() koje su po prirodi identične funkcijama scanf() i printf(), osim što je prvi argument FILE pokazivač koji ukazuje na datoteku iz koje se čita, odnosno u koju se piše. Formatirajuća niska (niz karaktera) je u ovom slučaju drugi argument.
Prototip funkcije za formatirani ulaz je:
int fscanf(FILE *fp, char *format,...)
Funkcija fscanf vraća kao rezultat broj učitanih parametara.
Prototip funkcije za formatirani izlaz je:
int fprintf(FILE *fp, char *format,...)
Ove funkcije su identične funkcijama scanf i printf samo što je prvi argument pokazivač datoteke koji određuje u koju se datoteku nešto upisuje ili iz koje datoteke se nešto čita. Pomenimo još i funkciju
int sscanf(const char *s, const char *format...)
Ona je identična sa scanf samo što ne učitava sa ulaza nego iz niske s.
LINK: Ako želite možete pogledati detaljniji opis formatiranog ulaza i izlaza KLIKOM ovde
U nastavku je dat primer upotrebe funkcije fprintf():
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE * fp;
fp= fopen("file.txt", "w+");
fprintf(fp, "%s %s %s %d", "Mi", "smo", "u godini", 2019);
fclose(fp);
return 0;
}
Nakon izvršenja programa kreiraće se datoteka file.txt u kojoj će biti upisan sledeći tekst:
Mi smo u 2019
U cilju boljeg uvida u funkciju fscanf() dat je i sledeći primer:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char str1[10], str2[10], str3[10];
int godina;
FILE * fp;
fp= fopen("file.txt", "w+");
fputs("Mi smo u 2019", fp);
rewind(fp);
fscanf(fp, "%s %s %s %d", str1, str2, str3, &godina);
printf("Read String1 |%s|\n", str1 );
printf("Read String2 |%s|\n", str2 );
printf("Read String3 |%s|\n", str3 );
printf("Read Integer |%d|\n", godina );
fclose(fp);
return 0;
}
Argumenti komandne linije
Prilikom pozivanja programa iz komandne linije moguće je navesti određene opcije i argumente, koje program koristi u svom radu. Npr, možemo pozvati program na sledeći način:
./izvrsni ulaz.txt izlaz.txt
želeći da program izvrsni iskopira fajl ulaz.txt u fajl izlaz.txt.
Potrebno je da postoji mehanizam da program iznutra pristupi stringovima koje je korisnik naveo prilikom poziva programa.
U C-u se to ostvaruje na sledeći način:
Definišemo parametre funkcije main:
int main(int argc, char *argv[])int argc ovaj parametar prilikom pokretanja programa dobija vrednost broja argumenata koje je korisnik prilikom poziva naveo. Pri tom se i ime programa broji kao argument komandne linije. U gornjem primeru će argc biti postavljeno na 3.
char **argv pokazivač na pokazivač na char koji sadrži adresu prvog u nizu pokazivača na karaktere. Svaki od tih pokazivača na karaktere sadrži adresu odgovarajućeg stringa koji sadrži argument komandne linije. Npr. u gornjem primeru, argv[0] će nam pokazivati na string "./primer", argv[1] će nam pokazivati na string "ulaz.txt", argv[2] će nam pokazivati na string "izlaz.txt". Dakle, niz pokazivača na čiji prvi član pokazuje argv je dužine upravo argc.
*(Funkcije sa promenljivim brojem argumenata su u knjizi u poglavlju 4.7, strana 66)
- Ako ovo nije jasno, drugi način za objašnjenje:
Čemu služe ovi argumenti funkcije main:
int main(int argc, char *argv[]) ????
Šta su i čemu služe argumenti nekog programa?
Probajte Start > Run
Kucajte: notepad
(otvoriće se Notepad)
Zatvorite notepad i kucajte ponovo: notepad c:\autoexec.bat
(otvoriće se istovremeno i datoteka autoexec.bat u Notepadu)
Drugim rečima, programi mogu imati još neke parametre (argumente) u nastavku, koji menjaju default ponašanje programa.
agrc (argument count) govori koliko ima argumenata u pokrenutom programu.
U prvom slučaju argc ima vrednost 1, jer postoji samo jedna stavka (program).
U drugom slučaju argc ima vrednost 2, jer postoje dve stavke (program i ime datoteke).
argv su pointeri na početak stringa svake stavke.
Kompajlirajte sledeći program:
#include <stdio.h>
#include <stdlib.h>
int main ( int argc, char *argv[] )
{
printf( "BROJ ARGUMENATA=%d\n\n", argc );
for( int i=0; i<argc; i++ )
printf("%d.ARGUMENT=%s\n", i, argv[i] );
getchar();
return 0;
}
program.exe jedan dva tri cetiri pet
... i pogledajte šta ce biti na ekranu:
BROJ ARGUMENATA=6
0.ARGUMENT=C:\Users\ucenik\Desktop\New Folder\program.exe
1.ARGUMENT=jedan
2.ARGUMENT=dva
3.ARGUMENT=tri
4.ARGUMENT=cetiri
5.ARGUMENT=pet
Press any key to continue . . .
LINK: Dodatno objašnjenje poslednjeg dela i par rešenih zadataka na KLIK ovde