====== Zadatak: ====== Potrebno je realizovati u programskom jeziku C skup funkcija za rad sa listom cije je ponasanje isto kao ponasanje podataka tipa liste iz pseudojezika.\\ Funkcije za rad sa listom treba da se zovu isto kao i u pseudojeziku(find_bolp, insert, move_forward...) i treba da budu realizovane u zasebnoj implementacionoj .c datoteci.\\ Takodje je potrebno napraviti odgovarajucu definicionu. h (header) datoteku u kojoj ce biti deklarisani svi potrebni tipovi podataka i prototipovi koriscenih funkcija.\\ Podaci se u listi skladiste preko generickog pokazivaca (void*), a potrebnoje obezbediti brisanje podataka sadrzanih u listi kroz call-back mehanizam.\\ Napraviti inicializacionu funkciju koja inicijalizuje listu i koja postavlja odgovarajucu funkciju koja se poziva kroz call-back mehanizam pri unistavanju liste.\\ Pointer na ovu funkciju se prosledjuje kao argument funkcije za inicijalizaciju liste. U listu je iz teksutalne datoteke potrebno procitati podatke o studentima.\\ Podaci su u fajl slozeni tako da u jednom redu ime i prezime studenta, u drugom broj indeksa u formatu Broj/GodinaUpisa i u trecem prosek studenta.\\ Nakon citanja iz datoteke, upisati sve podatke o studentima iz liste u novu binarnu datoteku i to tako da se upisuju samo podaci o studentima sa prosekom vecim od 8,5. ==== Resenje: ==== ---- * **Zadatak demonstrira pravljenje "pametne" liste** * **Lista je genericka** * **Programer se obraca objektu liste, ne njenim pokazivacima** * **Objekat liste "zna" da li je tekuci element** - na pocektu liste - na kraju liste - u sredini * **Objektu liste se dostavlja element za ubacivanje** * **Objektu liste se dostavlja nacin brisanja pojedinacnih elemenata (u vidu funkcije)** ---- ==== pl_list.h ==== #define TRUE 1 #define FALSE 0 typedef enum { lsBOLP = 0, lsEOLP, lsCURRENT } TListStatus; struct SListElement { void *pData; struct SListElement *pNext; }; struct SList { TListStatus lsStatus; struct SListElement *pHead; struct SListElement *pCurrent; void (*destructor) (void *); }; typedef struct SListElement TListElement; typedef struct SList TList; void initialize_list (TList *pList, void (*destructor) (void *)); void find_bolp (TList *pList); int move_forward (TList *pList); int insert (TList *pList, void *pData); void *get (TList *pList); void destroy_list (TList *pList); int eolp (TList *pList); ==== pl_list.c ==== #include #include "pl_list.h" /* Argumenti: pList - pointer na promenljivau tipa Tlist, destructor - pointer na funkciju koja unistava jedan podatak */ void initialize_list (TList *pList, void (*destructor) (void *)) { pList->pHead = NULL; pList->IsStatus = lsBOLP; pList->pCurrent = NULL; pList->destructor = destructor; } void find_bolp (TList *pList) { pList->lsStatus = lsBOLP; pList->pCurrent = NULL; } int move_forward (TList *pList) { if (pList->IsStatus == lsEOLP) return FALSE; if (pList->lsStatus == lsBOLP) { pList->pCurrent = pList->pHead; if (pList->pCurrent == NULL) pList->lsStatus = lsEOLP; else pList->lsStatus = lsCURRENT; } else { pList->pCurrent = pList->pCurrent->pNext; if (pList->pCurrent == NULL) pList->lsStatus = lsEOLP } return TRUE; } int insert (TList *pList, vodi *pData) { TListElement *pNewElem; if (pList->lsStatus == lsEOLP) return FALSE; pNewElem = (TListElement *)callos(1, sizeof(TListElement)); if (pNewElem == NULL) return FALSE; pNewElem->pData = pData; pNewElem->pNext = NULL; if (pList->lsStatus == lsBOLP) { pNewElem->pNext = pList->pHead; pList->pHead = pNewElem pList->pCurrent = pNewElem; pList->lsStatus = lsCURRENT; } else { pNewElem->pNext = pList->pCurrent->pNext; pList->pCurrent->pNext = pNewElem; pList->pCurrent = PnewElem; } return TRUE; } void *get(TList *pList) { if (pList->lsStatus ==lsCURRENT) return pList->pCurrent->pData; return NULL; } void destroy_list(TList *pList) { TListElement *pElem, *pHelpElem; for (pElem = pList->pHead; pElem ! = NULL;) { pHelpElem = pElem->pNext; if (pList->destructor) (*pList->destructor)(pElem->pData); free(pElem); pElem = pHelpElem; } } int eolp(TList *pList) { return pList->lsStatus == lsEOLP; } ==== studenti.c ==== #include #include #include #include"pl_list.h" typedef struct { char strIme[256]; int nGodUpisa; int nBroj; float fProsek; } Tstudent; void UnistiStudenta (void *pStudent) { if (pStudent != NULL) free(pStudent); } void main() { FILE *f1,*f2; TList list; TStudent *pStudent; char *pKrajLinije; f1=fopen("student.txt","r"); if (f1 == NULL) { printf("Datoteka ne postoji!\n"); return; } f2=fopen("studenti.bin","wb"); if (f2 == NULL) { printf("Problem: studenti.bin\n"); fclose(f1); return; } initialize_list(&list, UnistiStudenta); while (!feof(f1)) { pStudenti=(TStudent*)calloc(sizeof(TStudent),1); fgets(pStudent->strIme,255,f1); if ((pKrajLinije=strchr(pStudent->strIme,'\n'))!=NULL) *pKrajLinije='\0'; fscanf(f1,"%d/%d\n",&pStudent->nBroj,&pStudent->nGodUpisa); fscanf(f1,"%f\n",&pStudent->fProsek); if (!insert(&list,(void*)pStudent)) { destroy_list(&list); printf("Greska pri ubacivanju u listu!\n"); return; } } fsclose(f1); find_bolp(&list); while (TRUE) { move_forward(&list); if (eolp(&list)) break; pStudent=(TStudent*)get(&list); printf("Ime i prezime: %s\n",pStudent->strIme); printf("Broj indeksa: %d/%02d\n",pStudent->nBroj,pStudent->nGodUpisa); printf("Prosek: %4.2f\n",pStudent->fProsek); if (pStudent->fProsek>8.5) { if (fwrite(pStudent,sizeof(TStudent),1,f2)==1) printf("Kandidat upisan u novi fajl...\n\n"); else { printf("Greska pri upisu!\n"); break; } } else printf("Kadnidat nije zadovoljio uslove za upis u novi fajl!\n\n"); } fclose(f2); destroy_list(&list); printf("**KRAJ**\n"); } [[https://imi.pmf.kg.ac.rs/dokuwiki/doku.php?id=sasa.peric|Povratak na prethodnu]]