Datoteke
Select messages from
# through # FAQ
[/[Print]\]

Forum@DeGiorgi -> Programiranje 1 i 2

#1: Datoteke Autor/ica: krilo PostPostano: 9:32 uto, 6. 6. 2017
    —
Pozdrav Very Happy
Imam problem sa zadatkom iz poglavlja datoteka...

Napišite program koji čita datoteku "test.txt", te ju prepisuje u datoteku "izlaz.txt" tako da u prepisivanju sva pojavljivanja stringa "xa" zamijeni stringom "iweigjw".
Kod:

FILE* zamijeni(FILE *fpin, FILE *fpout)
{
    FILE *temp; char c;
    fscanf(fpin, "%c", &c); if (fpin==EOF) return NULL;
    if (c=='x')
        {
            temp=fpin;
            fscanf(fpin, "%c", &c);
            if (c=='a')
             {
                fprintf(fpout, "%s", "iweigjw");
             }
            else fprintf (fpout, "x%c", c);
        }
     else fprintf(fpout, "%c", c);
    return fpin;
}

int main(void)
{
    FILE *fpin, *fpout, *temp; char c;
    fpin=fopen("test.txt", "r");
    fpout=fopen("izlaz.txt", "w");

    while(fpin!=NULL)
        {
            fpin=zamijeni(fpin, fpout);
        }

    fclose(fpin); fclose(fpout);
    return 0;
}


Naime, sve se zamjene dobro obave, osim zadnje. Npr. za test.txt koji sadrži samo jedno slovo, to se slovo u izlaznu datoteku ispisuje unedogled. Znam da je problem u tome što se fpin (in-file-pointer) ne miče s tog zadnjeg slova, tj. nikad ne dođe do EOF-a, ali ne znam kako da to riješim bez uporabe fscanf-a i ponovnog učitavanja istog tog slova. Ideje?

#2: Re: Datoteke Autor/ica: mdokoLokacija: Heriot-Watt University, Edinburgh PostPostano: 17:47 sri, 7. 6. 2017
    —
krilo (napisa):
Kod:

    fscanf(fpin, "%c", &c); if (fpin==EOF) return NULL;


Ovo nikako ne može biti dobro. Naime, fpin je argument funkcije, a znamo da se u C-u argumenti predaju funkciji po vrijednosti, što znači da poziv fscanf(fpin, "%c", &c); ne može promijeniti vrijednost varijeble fpin. Je li tako?

Ajmo sad malo na priču o tome što tebi ovdje zapravo nije jasno.

Koliko ja vidim, ti se ponašaš kao da je fpin pointer na poziciju u datoteci koju čitaš i onda se čitanjem iz datoteke taj pointer pomiče po datoteci. Nažalost situacija nije tako jednostavna.

Ako malo promisliš, očito je da stvari ni ne mogu biti tako jednostavne. Naime, fpin je tipa FILE*, odnosno fpin je pointer na nešto što se zove FILE. (Kasnije ćemo o tome što je to nešto). Pointeri su varijable čiju vrijendost interpretiramo kao adresu neke memorijske lokacije. S druge strane, datoteke ne žive u memoriji nego na hard disku, SSD-u, CD-u, DVD-u, Google Driveu, Dropboxu i tko zna gdje drugo, ali ne u memoriji. Prema tome, pointer fpin koji pokazuje na nešto u memoriji nikako ne može pokazivati na poziciju u datoteci. Je li tako?

E, sad, na što fpin zapravo pokazuje?

Priča je ne baš skroz trivijalna. Naime, programi nikada ne komuniciraju direktno s datotekama, nego to rade posredno, putem operativnog sustava. Svaki program se vrti u okviru nekog operativnog sustava (GNU/Linux, Windows, Mac OS, BSD, Android, iOS i sl.), te kada treba komunicirati s datotekama, onda program zamoli operativni sustav da otvori komunikacijski kanal prema željenoj datoteci.

Kada u C-u napišeš fopen("test.txt", "r"), rekla si svom programu da prilikom izvršavanja te linije koda kaže operativnom sustavu, "Hej, OS, molim te da mi omogućiš čitanje iz datoteke test.txt.". Ako može, OS će onda alocirati "uređaj" preko kojeg tvoj program može komunicirati s traženom datotekom. Taj "uređej za komunikaciju s datotekom" je struktura tipa FILE, a povratna vrijednost funkcije fopen je pointer na tu strukturu.

E, dobro. A kako onda znamo kad smo na kraju datoteke?

Za to je dobro baciti oko na dokumentaciju funckije fscanf, gdje lijepo piše:
Documentation of fscanf (napisa):
On success the number of input fields converted and stored are returned. If an input failure occurred, then EOF is returned.

Dakle, treba provjeravati povratnu vrijednost funcije fscanf. Na primjer ovako:
Kod:
if(fscanf(fpin, "%c", &c) != EOF) {
  /* nesto smo procitali */
} else {
  /* dosli smo do kraja datoteke */
}




Je li sad jasnije? Ako nije, pitaj! Smile




Za znatiželjne: kako izgleda struktura FILE?
Spoiler [hidden; click to show]:

#3:  Autor/ica: krilo PostPostano: 20:45 čet, 8. 6. 2017
    —
Citat:
Prema tome, pointer fpin koji pokazuje na nešto u memoriji nikako ne može pokazivati na poziciju u datoteci.

Ahaaaaaaaaa Imam ideju!
E pa baš mi nikako nije bilo jasno što je taj EOF... ja sam mislila da je to neka vrsta oznake kao što je \0 na kraju stringa, pa se čudom čudim zašto fpin neće na njega "skočit".
Hvala na podrobnom objašnjenju Thank you Voljela bih da mi je to tako netko na predavanjima objasnio. Za svaku pohvalu Very Happy

#4:  Autor/ica: mdokoLokacija: Heriot-Watt University, Edinburgh PostPostano: 20:54 čet, 8. 6. 2017
    —
krilo (napisa):
E pa baš mi nikako nije bilo jasno što je taj EOF

EOF je vrijednost koju vraćaju funkcije koje rade s datotekama kada naiđu na kraj datoteke (ili u slučaju raznih grešaka).

Ako te zanima što je točno EOF:
stdio.h (napisa):
Kod:
#define EOF (-1)
Smile



Forum@DeGiorgi -> Programiranje 1 i 2


output generated using printer-friendly topic mod. Vremenska zona: GMT + 01:00.

Stranica 1 / 1.

Powered by phpBB © 2001,2002 phpBB Group
Theme created by Vjacheslav Trushkin