Search
 
 
  Engleski
 
 
 
Open in this window (click to change)
Forum@DeGiorgi: Početna
Forum za podršku nastavi na PMF-MO
Login Registracija FAQ Smajlići Članstvo Pretražnik Forum@DeGiorgi: Početna

Datoteke (zadatak)
WWW:

Moja sarma
 
Započnite novu temu   Odgovorite na temu   printer-friendly view    Forum@DeGiorgi: Početna -> Kolegiji 1. godine, preddiplomski studij Matematika -> Programiranje 1 i 2
Prethodna tema :: Sljedeća tema  
Autor/ica Poruka
krilo
Forumaš(ica)
Forumaš(ica)


Pridružen/a: 01. 11. 2016. (14:45:48)
Postovi: (4E)16
Spol: žensko
Sarma = la pohva - posuda
= 5 - 0

PostPostano: 9:32 uto, 6. 6. 2017    Naslov: Datoteke Citirajte i odgovorite

Pozdrav :D
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".
[code:1]
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;
}
[/code:1]

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


[Vrh]
Korisnički profil Pošaljite privatnu poruku
mdoko
Forumaš(ica)
Forumaš(ica)


Pridružen/a: 30. 11. 2002. (22:17:12)
Postovi: (71A)16
Spol: muško
Sarma = la pohva - posuda
199 = 237 - 38
Lokacija: Heriot-Watt University, Edinburgh

PostPostano: 17:47 sri, 7. 6. 2017    Naslov: Re: Datoteke Citirajte i odgovorite

[quote="krilo"][code:1]
fscanf(fpin, "%c", &c); if (fpin==EOF) return NULL;
[/code:1][/quote]

Ovo nikako ne može biti dobro. Naime, [tt]fpin[/tt] je argument funkcije, a znamo da se u C-u argumenti predaju funkciji [b]po vrijednosti[/b], što znači da poziv [tt]fscanf(fpin, "%c", &c);[/tt] ne može promijeniti vrijednost varijeble [tt]fpin[/tt]. 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 [tt]fpin[/tt] 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, [tt]fpin[/tt] je tipa [tt]FILE*[/tt], odnosno [tt]fpin[/tt] je pointer na nešto što se zove [tt]FILE[/tt]. (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 [tt]fpin[/tt] koji pokazuje na nešto u memoriji nikako ne može pokazivati na poziciju u datoteci. Je li tako?

E, sad, na što [tt]fpin[/tt] 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š [tt]fopen("test.txt", "r")[/tt], rekla si svom programu da prilikom izvršavanja te linije koda kaže operativnom sustavu, [i]"Hej, OS, molim te da mi omogućiš čitanje iz datoteke [tt]test.txt[/tt]."[/i]. 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 [tt]FILE[/tt], a povratna vrijednost funkcije [tt]fopen[/tt] 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 [tt]fscanf[/tt], gdje lijepo piše: [quote="[url=https://www-s.acm.illinois.edu/webmonkeys/book/c_guide/2.12.html#scanf]Documentation of [tt]fscanf[/tt][/url]"]On success the number of input fields converted and stored are returned. If an input failure occurred, then EOF is returned.[/quote]
Dakle, treba provjeravati povratnu vrijednost funcije [tt]fscanf[/tt]. Na primjer ovako: [code:1]if(fscanf(fpin, "%c", &c) != EOF) {
/* nesto smo procitali */
} else {
/* dosli smo do kraja datoteke */
}[/code:1]



Je li sad jasnije? Ako nije, pitaj! :)




Za znatiželjne: [b]kako izgleda struktura [tt]FILE[/tt]?[/b]
[spoiler]
U [tt]stdio.h[/tt] imamo (između ostalog) ove dvije linije: [code:1]#include <libio.h>
typedef struct _IO_FILE FILE;[/code:1]

Struktura [tt]_IO_FILE[/tt] definirana je u [tt]libio.h[/tt] na sljedeći način: [code:1]struct _IO_FILE {
int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
#define _IO_file_flags _flags

/* The following pointers correspond to the C++ streambuf protocol. */
/* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
char* _IO_read_ptr; /* Current read pointer */
char* _IO_read_end; /* End of get area. */
char* _IO_read_base; /* Start of putback+get area. */
char* _IO_write_base; /* Start of put area. */
char* _IO_write_ptr; /* Current put pointer. */
char* _IO_write_end; /* End of put area. */
char* _IO_buf_base; /* Start of reserve area. */
char* _IO_buf_end; /* End of reserve area. */
/* The following fields are used to support backing up and undo. */
char *_IO_save_base; /* Pointer to start of non-current get area. */
char *_IO_backup_base; /* Pointer to first valid character of backup area */
char *_IO_save_end; /* Pointer to end of non-current get area. */

struct _IO_marker *_markers;

struct _IO_FILE *_chain;

int _fileno;
#if 0
int _blksize;
#else
int _flags2;
#endif
_IO_off_t _old_offset; /* This used to be _offset but it's too small. */

#define __HAVE_COLUMN /* temporary */
/* 1+column number of pbase(); 0 is unknown. */
unsigned short _cur_column;
signed char _vtable_offset;
char _shortbuf[1];

/* char* _save_gptr; char* _save_egptr; */

_IO_lock_t *_lock;
#ifdef _IO_USE_OLD_IO_FILE
};

struct _IO_FILE_complete
{
struct _IO_FILE _file;
#endif
#if defined _G_IO_IO_FILE_VERSION && _G_IO_IO_FILE_VERSION == 0x20001
_IO_off64_t _offset;
# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
/* Wide character stream stuff. */
struct _IO_codecvt *_codecvt;
struct _IO_wide_data *_wide_data;
struct _IO_FILE *_freeres_list;
void *_freeres_buf;
size_t _freeres_size;
# else
void *__pad1;
void *__pad2;
void *__pad3;
void *__pad4;
size_t __pad5;
# endif
int _mode;
/* Make sure we don't get into trouble again. */
char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];
#endif
};[/code:1]
[/spoiler]
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]:



_________________
Extraordinary claims require extraordinary evidence. – Carl Sagan
[Vrh]
Korisnički profil Pošaljite privatnu poruku Posjetite Web stranice
krilo
Forumaš(ica)
Forumaš(ica)


Pridružen/a: 01. 11. 2016. (14:45:48)
Postovi: (4E)16
Spol: žensko
Sarma = la pohva - posuda
= 5 - 0

PostPostano: 20:45 čet, 8. 6. 2017    Naslov: Citirajte i odgovorite

[quote]Prema tome, pointer [tt]fpin[/tt] koji pokazuje na nešto u memoriji nikako ne može pokazivati na poziciju u datoteci.[/quote]
Ahaaaaaaaaa :idea2:
E pa baš mi nikako nije bilo jasno što je taj [tt]EOF[/tt]... ja sam mislila da je to neka vrsta oznake kao što je [tt]\0[/tt] na kraju stringa, pa se čudom čudim zašto [tt]fpin[/tt] neće na njega "skočit".
Hvala na podrobnom objašnjenju :thankyou: Voljela bih da mi je to tako netko na predavanjima objasnio. Za svaku pohvalu :D
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


[Vrh]
Korisnički profil Pošaljite privatnu poruku
mdoko
Forumaš(ica)
Forumaš(ica)


Pridružen/a: 30. 11. 2002. (22:17:12)
Postovi: (71A)16
Spol: muško
Sarma = la pohva - posuda
199 = 237 - 38
Lokacija: Heriot-Watt University, Edinburgh

PostPostano: 20:54 čet, 8. 6. 2017    Naslov: Citirajte i odgovorite

[quote="krilo"]E pa baš mi nikako nije bilo jasno što je taj [tt]EOF[/tt][/quote]
[tt]EOF[/tt] 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 [tt]EOF[/tt]:[quote="stdio.h"][code:1]#define EOF (-1)[/code:1][/quote] :)
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



_________________
Extraordinary claims require extraordinary evidence. – Carl Sagan
[Vrh]
Korisnički profil Pošaljite privatnu poruku Posjetite Web stranice
Prethodni postovi:   
Započnite novu temu   Odgovorite na temu   printer-friendly view    Forum@DeGiorgi: Početna -> Kolegiji 1. godine, preddiplomski studij Matematika -> Programiranje 1 i 2 Vremenska zona: GMT + 01:00.
Stranica 1 / 1.

 
Forum(o)Bir:  
Ne možete otvarati nove teme.
Ne možete odgovarati na postove.
Ne možete uređivati Vaše postove.
Ne možete izbrisati Vaše postove.
Ne možete glasovati u anketama.
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2002 phpBB Group
Theme created by Vjacheslav Trushkin
HR (Cro) by Ančica Sečan