Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /************************************
- T E L E F O N S K I ___ I M E N I K
- +++++++++++++++++++++++++++++++++++++++
- Ucitati podatke o osobama iz datoteke, cije se ime zadaje
- preko terminala pri pozivu programa.
- Podatke iz datoteke smestiti u jednostruko spregnutu listu (JSL)
- Napraviti korisnicki meni sa opcijama:
- 1. Sort liste po imenima
- 2. Sort list po prezimenima
- 3. Sort po brojavima
- 4. Prikaz svih osoba cije prezime pocinje na odredjeno slovo
- 5. Brisanje iz liste svih osoba cije prezime pocinje na odredjeno slovo
- 6. Upis cele liste u datoteku
- 1337. izlaz
- Broj telefona je uvek CEO BROJ!
- 0,1,2,3,4,5...999 999
- Podaci u datoteci izgledaju ovako:
- Petar Petrovic 12
- Nikola Nikolic 39
- Jovan Jovanovic
- ****************************************/
- #include <stdio.h>
- #include <stdlib.h> /* zbog exit funkcije */
- #include <errnu.h>
- struct Podaci {
- char ime[MAX];
- char prezime[MAX];
- int broj;
- };
- struct CVOR{
- struct Podaci x; // sve lepo zapakovano
- struct CVOR* sledeci;
- };
- // pokazivac na glavu, jer se glava mora modifikovati
- // kada se dodaje prvi element, da glava pokazuje na njega
- void dodajElement(struct CVOR** pGlava, struct Podaci podaci);
- void sortPoImenima(struct CVOR* glava);
- void sortPoPrezimenima(struct CVOR* glava);
- void sortPoBrojevima(struct CVOR* glava);
- void prikazSvihNaSlovo(struct CVOR* glava, char slovo);
- void brisiBroj(struct CVOR** pGlava, int broj);
- void upisUDatoteku(struct CVOR* glava);
- void ispisNaEkran(struct CVOR* glava);
- void unistiListu (struct CVOR** pGlava);
- void ucitajIzDatoteke(struct CVOR**, char* imeDat);
- void ispisJednogCvora(struct CVOR* cvor);
- // ./program ulaz.txt izlaz.txt
- int main(int brArg, char** args)
- {
- FILE* pfUlaz;
- FILE* pfIzlaz;
- struct CVOR* glava = NULL; /* prazna lista na pocetku !1!! s*/
- struct Podaci podaci; // podaci za tastature
- // da mogu da se lepo upakuju i proslede kao parametar
- // funkciji za dodavanje novog elementa u listu
- int izbor; /* izbor opcije iz menija */
- char slovo; /* za prikaz zeljenih prezimena */
- int brojTelefona;
- // O T VARANJE DATOTEKA ZA DALJI RAD
- ///////////////////////////////////////////
- pfUlaz = fopen(args[1], "r");
- if (pfUlaz == NULL)
- {
- printf("Datoteka nije otvorena zbog:");
- perror(errno);
- return -1; // fail, program ne moze da nastavi dalje
- }
- pfIzlaz = fopen(args[2], "w");
- if (pfUlaz == NULL)
- {
- printf("Datoteka nije otvorena zbog:");
- perror(errno);
- return -1; // fail, program ne moze da nastavi dalje
- }
- //////////////////////////////////////
- // ucitavanje liste iz ulazne datoteke
- while( fscanf(pfUlaz, "%s ", podaci.ime) != EOF)
- { // ako je uspeo da ucita ime, valjda ostatak podataka stoji
- // u nastavku
- // !=EOF, OK IMA STA DA SE CITA!
- // ime niza je pokazivac na nulti clan,
- fscanf(pfUlaz, "%s ", podaci.prezime);
- fscanf(pfUlaz , "%d", &podaci.broj);
- // podatke iz datoteke smo zapakovali u strukturu podaci
- // saljemo je funkciji da u novi element upise te podatke
- // u novi cvor (koga ce jelte, napraviti prvo)
- dodajElement(&glava, podaci);
- }
- fclose(pfUlaz);
- // sve ok za sada
- do
- {
- printf("1. Sort liste po imenima\n");
- printf("2. Sort list po prezimenima\n");
- printf("3. Sort po brojevima\n");
- printf("4. Prikaz svih osoba cije prezime pocinje na odredjeno slovo\n");
- printf("5. Brisanje iz liste osobe sa nekim brojem telefona\n");
- printf("6. Upis cele liste u izlaznu datoteku\n");
- printf("7. Ispis cele liste na ekran\n");
- printf("8. Unisti listu \n");
- printf("9. Ucitaj listu iz ulazne datoteke\n");
- scanf("%d", &izbor);
- switch(izbor)
- {
- case 1:
- // ne treba adresa glave, jer ne diramo glavu, niti listu celu
- // samo obrcemo sadrzaj
- // x od jednog cvora upisemo u x od drugog cvora
- // i to je to!
- sortPoImenima(glava);
- break;
- case 2:
- sortPoPrezimenima(glava);
- break;
- case 3:
- sortPoBrojevima(glava);
- break
- case 4:
- printf("Unesite slovo\n");
- scanf("%c", &slovo);
- prikaziNaSlovo(glava, slovo);
- break;
- case 5:
- printf("Unesite broj telefona\n");
- scanf("%c", &brojTelefona);
- // adresa glave se daje
- // sta ako je u pitanju prvi element?
- // onda lista mora da pokazuje na sledeceg
- // ili ako je prvi jedini, glava treba da je NULL
- brisiBroj(&glava, brojTelefona);
- break;
- case 6:
- upisUDatoteku(glava);
- break;
- case 7:
- ispisNaEkran(glava);
- case 8:
- // mora adres aglave da bi se postavila na NULL
- // kada ne bude vise liste
- unistiListu(&glava);
- case 9:
- // mora adresa glave , jer ce se menjati
- // formira se nova lista
- ucitajIzDatoteke(&glava, args[1]);
- break;
- default:
- printf("Greska! Los izbor: 1~9\n");
- }
- }while(izbor!=1337);
- ///////////////////////////////////////////
- }
- void dodajElement(struct CVOR** pGlava, struct Podaci podaci)
- {
- struct CVOR* novi; // cuva adresu koju malloc vrati
- struct CVOR* trenutni; // za kretanje kroz listu, jer glavu NE KORISTIMO ZA KRETANJE KROZ LISTU, jer bi nam se lista raspala!!
- // napravimo novi element, kasnije cemo ga uvezati u listu
- novi = (struct CVOR*) malloc (sizeof(struct CVOR));
- if (novi == NULL)
- {
- printf("NEMA DOVOLJNO MEMORIJE ZA RAD PROGRAMA!");
- exit(EXIT_FAILURE); // exit funkcija zavrsava ceo program cak iako je u funkciji
- }
- novi->sledeci = NULL;
- novi->x = podaci;
- if (*pGlava == NULL)
- {
- // prazna lista
- // glava pokazuje sada na prvi (jedini) element liste
- *pGlava = novi; // deref pokazivac da bi izmenio ono na sta on pokazuje (glavu iz mejna)
- }
- else
- {
- trenutni = *pGlava;
- /* idemo do poslednjeg elementa u listi
- trenutni ce pokazivati na njeega
- poslednji element u listi je onaj
- kome je polje sledecei jednako NULL
- U to polje cemo upisati adresu novog elementa
- i to je to
- */
- while(trenutni->sledeci != NULL)
- // kada se while zavrsi, bicemo sigurni da smo dosli do poslednjeg elementa
- // trenutni ce u sebi drzati adresu poslednjeg elementa liste
- {
- // prelazimo na sledeci element liste
- trenutni = trenutni ->sledeci;
- }
- //
- // sada samo da napisemo da poslednji pokazuje na novi
- trenutni->sledeci = novi;
- }
- }
- void sortPoImenima(struct CVOR* glava)
- {
- struct CVOR* i; /* ovog poredimo sa ostatkom liste */
- struct CVOR* j; //* j su ostali elementi sa kojima poredimo i */
- struct Podaci trecaCasa;
- // treca casa je tipa struktura koja u sebi samo cuva podatke cvora
- // jer samo njih i obrcemo
- i = *pGlava;
- /* idemo bubble sort
- for(i = 0; i< n - 1; i++)
- for ( j = i + 1; j < n; j++)
- if ( niz[j] < niz[i])
- {
- trecaCasa = niz[j];
- niz[j] = niz[i];
- niz[i] = trecaCasa;
- }
- */
- while (i->sledeci!=NULL)
- {
- j = i->sledeci;
- while(j!=NULL)
- {
- // izvucemo prvo slovo imena
- // u ASCII tabeli B je vece od A
- // A = 65, B = 66....
- if ( j->x.ime[0] > i->x.ime[0])
- {
- // obrcem sadrzaj cvorova i, j
- trecaCasa = j->x; // sadrzaj cvora j u pomocnu
- j->x = i->x; // sadrzaj cvora i ide u cvor j
- i->x = trecaCasa; // prethodno sacuvan
- // sadrzaj cvor j, sada ide u cvor i
- }
- // j ide dalje
- // jer za svaki i, treba otici od i+1 do kraja liste
- j = j -> sledeci;
- }
- // ako je j stiglo do kraja liste, to znaci da je sada == NULL
- // pomeramo i na sledeci cvor
- i = i -> sledeci;
- }
- }
- void sortPoPrezimenima(struct CVOR* glava)
- {
- struct CVOR* i; /* ovog poredimo sa ostatkom liste */
- struct CVOR* j; //* j su ostali elementi sa kojima poredimo i */
- struct Podaci trecaCasa;
- // treca casa je tipa struktura koja u sebi samo cuva podatke cvora
- // jer samo njih i obrcemo
- i = *pGlava;
- /* idemo bubble sort
- for(i = 0; i< n - 1; i++)
- for ( j = i + 1; j < n; j++)
- if ( niz[j] < niz[i])
- {
- trecaCasa = niz[j];
- niz[j] = niz[i];
- niz[i] = trecaCasa;
- }
- */
- while (i->sledeci!=NULL)
- {
- j = i->sledeci;
- while(j!=NULL)
- {
- // izvucemo prvo slovo prezimena
- // u ASCII tabeli B je vece od A
- // A = 65, B = 66....
- if ( j->x.prezime[0] > i->x.prezime[0])
- {
- // obrcem sadrzaj cvorova i, j
- trecaCasa = j->x; // sadrzaj cvora j u pomocnu
- j->x = i->x; // sadrzaj cvora i ide u cvor j
- i->x = trecaCasa; // prethodno sacuvan
- // sadrzaj cvor j, sada ide u cvor i
- }
- // j ide dalje
- // jer za svaki i, treba otici od i+1 do kraja liste
- j = j -> sledeci;
- }
- // ako je j stiglo do kraja liste, to znaci da je sada == NULL
- // pomeramo i na sledeci cvor
- i = i -> sledeci;
- }
- }
- void sortPoBrojevima(struct CVOR* glava)
- {
- struct CVOR* i; /* ovog poredimo sa ostatkom liste */
- struct CVOR* j; //* j su ostali elementi sa kojima poredimo i */
- struct Podaci trecaCasa;
- // treca casa je tipa struktura koja u sebi samo cuva podatke cvora
- // jer samo njih i obrcemo
- i = *pGlava;
- /* idemo bubble sort
- for(i = 0; i< n - 1; i++)
- for ( j = i + 1; j < n; j++)
- if ( niz[j] < niz[i])
- {
- trecaCasa = niz[j];
- niz[j] = niz[i];
- niz[i] = trecaCasa;
- }
- */
- while (i->sledeci!=NULL)
- {
- j = i->sledeci;
- while(j!=NULL)
- {
- if ( j->x.broj > i->x.broj)
- {
- // obrcem sadrzaj cvorova i, j
- trecaCasa = j->x; // sadrzaj cvora j u pomocnu
- j->x = i->x; // sadrzaj cvora i ide u cvor j
- i->x = trecaCasa; // prethodno sacuvan
- // sadrzaj cvor j, sada ide u cvor i
- }
- // j ide dalje
- // jer za svaki i, treba otici od i+1 do kraja liste
- j = j -> sledeci;
- }
- // ako je j stiglo do kraja liste, to znaci da je sada == NULL
- // pomeramo i na sledeci cvor
- i = i -> sledeci;
- }
- }
- void prikazSvihNaSlovo(struct CVOR* glava, char slovo)
- {
- struct CVOR* trenutni;
- trenutni = glava;
- // do kraja liste
- // kraj je kada trneutni uzme sadrzaj polaj sledeci
- while(trenutni!=NULL)
- {
- if (trenutni->x.prezime[0] == slovo)
- {
- ispisJednogCvora(trenutni);
- }
- trenutni = trenutni ->sledeci;
- }
- }
- void brisiBroj(struct CVOR** pGlava, int broj)
- {
- struct CVOR* trenutni;
- struct CVOR* prethodni;
- prethodni = glava;
- // napomena: BROJEVI TELEFONA SU JEDINSTVENI
- while(prethodni!=NULL)
- {
- // do kraja liste
- // kraj je kada trneutni uzme sadrzaj polaj sledeci
- trenutni = prethodni;
- while(trenutni!=NULL)
- {
- if (trenutni->x.broj == broj)
- {
- printf("\n\nCVOR ZA BRISANJE:\n");
- ispisJednogCvora(trenutni);
- }
- trenutni = trenutni->sledeci;
- }
- prethodni = prethodni -> sledeci;
- }
- // nakon ove dve while petlje
- // nasli smo cvor sa trazenim brojem
- // da li je mozda to prvi cvor liste i jos uz to JEDINI CVOR LISTE??
- if ( trenutni == *pGlava && trenutni->sledeci == NULL)
- {
- // onda nakon brisanja ovog elementa, dobicemo praznu listu
- free(trenutni);
- *pGlava = NULL;
- }
- // sta ako je prvi element, ali nije jedini?
- else if(trenutni == *pGlava && trenutni->sledeci != NULL)
- {
- // glavu treba pomeriti na drugi element, pre nego sto oslobodimo prvi element
- *pGlava = trenutni->sledeci; // glava na onaj posle prvog
- free(trenutni);
- }
- // ok nije na pocetku, definitino, ajde da vidimo da li je u sredini?
- // to znaci da trenutni->sledeci nije jednak NULL, jer ima nekog posle njega
- // to znaci da ima neko i PRE njega (prehtodni)
- else if (trenutni != *pGlava && trenutni-> sledeci != NULL)
- {
- // ako ima nekog iza njega
- // i nije prvi
- // to znaci da onaj iza njega TREBA DA POKAZUJE na onog ispred njega
- // primer, ovo je CVOR #2, njega brisemo
- // iza njega je CVOR#1
- // ispred je CVOR#3
- // pre nego sto izbrisemo CVOR#2
- // CVOR#1 mora da pokazuje na CVOR#3, kako se lista ne bi raspala
- // CVOE#1 je prethodni
- // CVOR#3 je CVOR#2->sledeci
- prethodni->sledeci = trenutni -> sledeci;
- free(trenutni);
- }
- // jos jedan slucaj!
- // STA AKO JE cvor koji se brise POSLEDNJI?
- else if ( trenutni != *pGlava && trenutni->sledeci == NULL)
- {
- // tada prethodni treba da pokazuje na NULL
- prethodni->sledeci = NULL;
- free(trenutni);
- }
- }
- }
- void upisUDatoteku(struct CVOR* glava)
- {
- }
- void ispisNaEkran(struct CVOR* glava)
- {
- struct CVOR* trenutni;
- trenutni = glava;
- // do kraja liste
- // kraj je kada trneutni uzme sadrzaj polaj sledeci
- while(trenutni!=NULL)
- {
- ispisJednogCvora(trenutni);
- trenutni = trenutni ->sledeci;
- }
- }
- void unistiListu (struct CVOR** pGlava);
- void ucitajIzDatoteke(struct CVOR** pGlava, char* imeDat)
- {
- *pGlava = NULL;
- FILE* pfUlaz;
- struct Podaci podaci;
- // O T VARANJE DATOTEKA ZA DALJI RAD
- ///////////////////////////////////////////
- pfUlaz = fopen(imeDat, "r");
- if (pfUlaz == NULL)
- {
- printf("Datoteka nije otvorena zbog:");
- perror(errno);
- return -1; // fail, program ne moze da nastavi dalje
- }
- //////////////////////////////////////
- // ucitavanje liste iz ulazne datoteke
- while( fscanf(pfUlaz, "%s ", podaci.ime) != EOF)
- { // ako je uspeo da ucita ime, valjda ostatak podataka stoji
- // u nastavku
- // !=EOF, OK IMA STA DA SE CITA!
- // ime niza je pokazivac na nulti clan,
- fscanf(pfUlaz, "%s ", podaci.prezime);
- fscanf(pfUlaz , "%d", &podaci.broj);
- // podatke iz datoteke smo zapakovali u strukturu podaci
- // saljemo je funkciji da u novi element upise te podatke
- // u novi cvor (koga ce jelte, napraviti prvo)
- // imamo vec adresu glave u pokazivacu na Glavu
- // NECEMO DATI ADRESU POKAZIVACA NA GLAVU!
- // nego vrednost tog pokazivaca (on u sebi cuva &glava)
- dodajElement(pGlava, podaci);
- }
- }
- void ispisJednogCvora(struct CVOR* cvor)
- {
- printf("Ime:%s\n", cvor->x.ime);
- printf("Prezime:%s\n", cvor->x.prezime);
- printf("Broj telefona:%d\n", cvor->x.broj);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement