Rezervacija karata za baletsku predstavu

Autor zadatka: Olja Anđelovski <andjelovski.olja@uns.ac.rs>

Iz zadate ulazne datoteke učitati podatke u jednostruko spregnutu listu. Podatke učitati u rastućem redosledu po rednom broju rezervisanog sedišta. Struktura balet sadrži sledeća polja:

  • redni broj rezervisanog sedišta (pozitivna celobrojna vrednost)

  • naziv baleta (jedna reč, do 8 karaktera)

  • rezervisao (jedna reč, do 25 karaktera)

  • cena (pozitivna celobrojna vrednost)

Takođe, struktura balet sadrži i polja potrebna za pravilno formiranje jednostruko spregnute liste.

Od korisnika zatražiti da unese naziv baleta (jedna reč, do 8 karaktera) i za uneti balet na terminal ispisati naziv baleta, ukupan broj prodatih karata i ukupnu cenu karata. Ispisati i podatke o rezervisanom sedištu, kupcu koji je rezervisao i ceni karte (ispoštovati očekivani izlaz prikazan u stavci pod rednim brojem 4.).

Napomene:

  • Prilikom unosa naziva baleta od strane korisnika voditi računa o tome da program treba da prepozna naziv baleta bez obzira na kombinaciju malih i velikih slova koje je korisnik uneo (pogledati stavku pod rednim brojem 2. npr. ukoliko korisnik unese „zizela”, u izlaznu datoteku treba ispisati informacije o prepoznatom baletu sa nazivom „Zizela”).

  • Kroz argumente komandne linije proslediti naziv ulazne datoteke.

  • Ukoliko za unete podatke od strane korisnika ne postoje podaci očekivan izlaz je prikazan u stavci pod rednim brojem 5.

  1. Primer poziva:

    ./a.out balet.txt
    
  2. Unos naziva baleta preko terminala:

    Naziv baleta: zizela
    
  3. Zadati ulaz u datoteci balet.txt:

5 Zizela Nadezda 310
11 Kopelija Nikola 230
23 Kopelija Milica 150
3 Zizela Igor 310
9 Pinokio Aleksandar 330
10 Zizela Ilija 250
22 Kopelija Milan 150
11 Zizela Stefan 250
  1. Očekivani izlaz na terminal ukoliko postoje podaci:

    Ukupno prodatih karata za balet pod nazivom Zizela je 4.
    Ukupna zarada je 1120 dinara.
    
    Sediste: 3 Rezervisao: Igor Cena: 310 din
    Sediste: 5 Rezervisao: Nadezda Cena: 310 din
    Sediste: 10 Rezervisao: Ilija Cena: 250 din
    Sediste: 11 Rezervisao: Stefan Cena: 250 din
    
  2. Očekivani izlaz na terminal ukoliko ne postoje podaci:

    Za unete podatke od strane korisnika ne postoje podaci.
    

Primer rešenja

  1#include <stdio.h>
  2#include <stdlib.h>
  3#include <string.h>
  4
  5#define MAX_REZERVISAO 26
  6#define MAX_NAZIV_BALETA 9
  7
  8typedef struct balet {
  9    unsigned sediste;
 10    char nazivBaleta[MAX_NAZIV_BALETA];
 11    char rezervisao[MAX_REZERVISAO];
 12    unsigned cena;
 13    struct balet *next;
 14}BALET;
 15
 16void init_list(BALET **head) {
 17    *head = NULL;
 18}
 19
 20char *lower(char str[]) {
 21    int i;
 22
 23    for(i=0; i<strlen(str); i++) {
 24        if(str[i] >= 65 && str[i] <= 90) {
 25            str[i] = str[i]+32;
 26        }
 27    }
 28
 29    return str;
 30}
 31
 32void add_to_list(BALET *new, BALET **head) {
 33    if(*head == NULL) { 
 34        *head = new;
 35        return;
 36    } 
 37    
 38    if((*head)->sediste > new->sediste) {
 39        new->next = *head;
 40        *head = new;
 41    } else {
 42        BALET* tek = *head;
 43        BALET* pret = *head;
 44        while(tek != NULL && tek->sediste < new->sediste) {
 45            pret = tek;
 46            tek = tek->next;
 47        }
 48        new -> next = pret -> next;
 49        pret -> next = new;
 50    }    
 51}
 52
 53BALET *create_new_item(unsigned sediste, char nazivBaleta[], 
 54char rezervisao[], unsigned cena) {
 55    BALET *new = (BALET*)malloc(sizeof(BALET));
 56    if (new == NULL) {
 57        printf("Nema dovoljno memorije!\n");
 58        exit(21);
 59    }
 60
 61    new->sediste = sediste;
 62    strcpy(new->rezervisao, rezervisao);
 63    strcpy(new->nazivBaleta, nazivBaleta);
 64    new->cena = cena;
 65
 66    new->next = NULL;
 67
 68    return new;
 69}
 70
 71void read_list_from(FILE *in, BALET **head) {
 72    unsigned sediste;
 73    char rezervisao[MAX_REZERVISAO];
 74    char nazivBaleta[MAX_NAZIV_BALETA];
 75    unsigned cena;
 76    
 77    while(fscanf(in, "%u %s %s %u", &sediste, nazivBaleta, rezervisao, &cena)
 78        != EOF) {
 79        BALET *new = create_new_item(sediste, nazivBaleta, rezervisao, cena);
 80        add_to_list(new, head);
 81    }
 82}
 83
 84void save(int postoji, BALET *head, char naziv[]){
 85    char nazivBaleta[MAX_NAZIV_BALETA];
 86    if(postoji==1){
 87         while(head != NULL) {
 88            strcpy(nazivBaleta,head->nazivBaleta); 
 89            if (strcmp(lower(naziv),
 90            lower(head->nazivBaleta)) == 0) {
 91                printf("Sediste: %u \t Rezervisao: %s \t Cena: %u din\n",
 92                head->sediste, head->rezervisao, head->cena);
 93            }
 94            head = head->next;
 95        }
 96    }
 97}
 98
 99void save_item_to(int *postoji, unsigned ukupnaCena, 
100char naziv[], unsigned brojKarata) {
101    if(*postoji==1){ 
102        printf("\nUkupno prodatih karata za balet "
103        "pod nazivom %s je %u.\n"
104        "Ukupna zarada je %u dinara.\n\n", 
105            naziv, brojKarata, ukupnaCena);
106    }
107    else{
108        printf("\nZa unete podatke od strane korisnika"
109        " ne postoje podaci.\n\n");
110    }
111}
112
113void destroy_list(BALET **head) {
114    if(*head != NULL) {
115        destroy_list(&((*head)->next));
116        free(*head);
117        *head = NULL;
118    }
119}
120
121FILE *safe_fopen(char *filename, char *mode, int error_code) {
122    FILE *fp = fopen(filename, mode);
123    if (fp == NULL) {
124        printf("Nije moguce otvoriti datoteku '%s'!\n", filename);
125        exit(error_code);
126    }
127    return fp;
128}
129
130void algoritam(char naziv[], BALET *head, int *postoji){
131    unsigned ukupnaCena = 0;    
132    unsigned brojKarata = 0;
133    char nazivBaleta[MAX_NAZIV_BALETA];
134    char nB[MAX_NAZIV_BALETA];
135
136    if (head == NULL) { 
137        return;    
138    }
139
140    while(head != NULL) {
141        strcpy(nazivBaleta,head->nazivBaleta);    
142           if (strcmp(lower(naziv),lower(nazivBaleta)) == 0) {
143            strcpy(nB, head->nazivBaleta);
144            ukupnaCena += head->cena;
145            brojKarata++;
146            *postoji=1;    
147        }    
148        head = head->next;
149    }
150    save_item_to(postoji, ukupnaCena, nB, brojKarata);
151}
152
153int main(int arg_num, char *args[]) {
154    if (arg_num != 2) {
155        printf("Program treba pozvati na sledeci nacin: "
156        "%s nazivUlazneDatoteke.txt\n", args[0]);
157        exit(11);
158    }
159    
160    int postoji=0;
161    char *in_filename = args[1];
162
163    FILE *in  = safe_fopen(in_filename,  "r", 1);
164
165    char naziv[MAX_NAZIV_BALETA];
166
167    printf("\nNaziv baleta: ");
168    scanf("%s", naziv);
169
170    BALET *head;
171    init_list(&head);
172
173    read_list_from(in, &head);
174  
175    algoritam(naziv, head, &postoji);
176    save(postoji, head, naziv);
177    destroy_list(&head);
178
179    fclose(in);
180
181    return 0;
182}