Ide gas

Autor zadatka: Rade Radišić <radisic.rade@uns.ac.rs>

Stambena jedinica je predstavljena preko strukture koja se sastoji od sledećih polja:

  • Ime vlasnika stana (jedna reč, maksimalno 20 karaktera)

  • Prezime vlasnika stana (jedna reč, maksimalno 30 karaktera)

  • Kvadratura stana (neoznačena, celobrojna vrednost)

Podaci o stambenim jedinicama u zgradi učitavaju se iz ulaznog fajla u jednostruko spregnutu listu, gde se čvorovi dodaju na kraj liste. S obzirom na to da zgrada nema kalorimetre za svaku stambenu jedinicu, naplata ukupno potrošenog gasa za mesec raspodeljuje se između stambenih jedinica na osnovu kvadrature stana po sledećoj formuli:

\[Potrošnja_{stan}[din] = Kv_{stan}[m^2] \div Kv_{zgrada}[m^2] \cdot Potrošnja_{zgrada}[din]\]

Ukupan račun za stambenu jedinicu je potrošnja stana, sa PDV-om od 10%.

Za zadati mesec, godinu i ukupnu potrošnju tokom meseca, potrebno je izračunati koliko je svaka stambena jedinica dužna da plati račun za gas. U izlaznu datoteku, potrebno je ispisati ime i prezime vlasnika stana, kao i cenu koju je vlasnik stambene jedinice dužan da plati u formatu "%-7s %-10s %.2lf". Naziv ulazne datoteke, mesec, godina i ukupna potrošnja tokom meseca, izražena u dinarima, zadaju se kao argumenti komandne linije. Naziv izlazne datoteke formira se spajanjem argumenata komandne linije za mesec i godinu i dodavanjem ekstenzije .txt.

Primer ulaznog fajla zgrada.txt

Petra  Petrovic   45
Mile   Milenkovic 56
Gorana Goric      37
Lazar  Lazetic    51
Rajko  Radovic    32
Milica Mitrovic   21
Aleksa Aleksic    43

Primer poziva programa:

./racun zgrada.txt decembar 2021 12510.54

Primer izlazne datoteke decembar2021.txt:

Petra   Petrovic   2172.88
Mile    Milenkovic 2704.03
Gorana  Goric      1786.59
Lazar   Lazetic    2462.60
Rajko   Radovic    1545.16
Milica  Mitrovic   1014.01
Aleksa  Aleksic    2076.31

Primer rešenja

  1#include <stdio.h>
  2#include <string.h>
  3#include <stdlib.h>
  4
  5#define MAX_IME 21
  6#define MAX_PREZIME 31
  7
  8#define MAX_IZLAZNA_DAT 18 // mesec(9) + godina(4) + ".txt"(4) + '\0'(1)
  9
 10typedef struct stambene_jedinice_st {
 11    char ime[MAX_IME];
 12    char prezime[MAX_PREZIME];
 13    unsigned kvadratura_stana;
 14    struct stambene_jedinice_st *sledeci;
 15} ST_JEDINICA;
 16
 17FILE *safe_fopen(char *, char *, int);
 18void ucitaj_kandidate(FILE *, ST_JEDINICA **);
 19void ispisi_racune(FILE *, ST_JEDINICA *, double);
 20
 21void inicijalizacija(ST_JEDINICA **);
 22ST_JEDINICA *napravi_cvor(char *, char *, unsigned);
 23void dodaj_na_kraj(ST_JEDINICA **, ST_JEDINICA *);
 24unsigned ukupna_kvadratura(ST_JEDINICA *);
 25void obrisi_listu(ST_JEDINICA **);
 26
 27double potrosnja_po_stanu(unsigned, unsigned, double);
 28double uvecaj_za_porez(double, double);
 29
 30int main(int argc, char **argv) {
 31    ST_JEDINICA *glava;
 32
 33    if(argc != 5) {
 34        printf("Primer poziva: %s zgrada.txt decembar 2021 12510.54\n", argv[0]);
 35        exit(EXIT_FAILURE);
 36    }
 37
 38    inicijalizacija(&glava);
 39
 40    FILE *ulazna = safe_fopen(argv[1], "r", 3);
 41    ucitaj_kandidate(ulazna, &glava);
 42    fclose(ulazna);
 43
 44    double ukupna_potrosnja = atof(argv[4]);
 45    char izlazna_dat[MAX_IZLAZNA_DAT];
 46    strcpy(izlazna_dat, argv[2]);
 47    strcat(izlazna_dat, argv[3]);
 48    strcat(izlazna_dat, ".txt");
 49    FILE *izlazna = safe_fopen(izlazna_dat, "w", 4);
 50    ispisi_racune(izlazna, glava, ukupna_potrosnja);
 51    fclose(izlazna);
 52
 53    obrisi_listu(&glava);
 54
 55    return EXIT_SUCCESS;
 56}
 57
 58FILE *safe_fopen(char *name, char *mode, int error_code) {
 59    FILE *fp = fopen(name, mode);
 60
 61    if(fp == NULL) {
 62        printf("Nije moguce otvoriti fajl %s!\n", name);
 63        exit(error_code);
 64    }
 65
 66    return fp;
 67}
 68
 69void ucitaj_kandidate(FILE *ulazna, ST_JEDINICA **pglava) {
 70    char tmp_ime[MAX_IME];
 71    char tmp_prezime[MAX_PREZIME];
 72    unsigned tmp_kvadratura_stana;
 73
 74    while(fscanf(ulazna, "%s %s %u",
 75                 tmp_ime,
 76                 tmp_prezime,
 77                 &tmp_kvadratura_stana
 78          ) != EOF) {
 79        ST_JEDINICA *novi = napravi_cvor(tmp_ime, tmp_prezime, tmp_kvadratura_stana);
 80        dodaj_na_kraj(pglava, novi);
 81    }
 82}
 83
 84void ispisi_racune(FILE *izlazna, ST_JEDINICA *glava, double ukupna_potrosnja) {
 85    ST_JEDINICA *tekuci = glava;
 86    unsigned kvadratura_zgrade = ukupna_kvadratura(glava);
 87
 88    while(tekuci != NULL) {
 89        double potrosnja = potrosnja_po_stanu(
 90                               tekuci->kvadratura_stana, kvadratura_zgrade, ukupna_potrosnja);
 91        double racun = uvecaj_za_porez(potrosnja, 10);
 92        fprintf(izlazna, "%-7s %-10s %.2lf\n", 
 93            tekuci->ime, tekuci->prezime, racun);
 94
 95        tekuci = tekuci->sledeci;
 96    }
 97}
 98
 99void inicijalizacija(ST_JEDINICA **pglava) {
100    *pglava = NULL;
101}
102
103ST_JEDINICA *napravi_cvor(char *ime, char *prezime, unsigned kvadratura_stana) {
104    ST_JEDINICA *novi = (ST_JEDINICA *) malloc(sizeof(ST_JEDINICA));
105
106    if(novi == NULL) {
107        printf("Greska prilikom zauzimanja memorije!\n");
108        exit(2);
109    }
110
111    strcpy(novi->ime, ime);
112    strcpy(novi->prezime, prezime);
113    novi->kvadratura_stana = kvadratura_stana;
114
115    novi->sledeci = NULL;
116
117    return novi;
118}
119
120void dodaj_na_kraj(ST_JEDINICA **pglava, ST_JEDINICA *novi) {
121    if(*pglava == NULL) {
122        *pglava = novi;
123    } else {
124        ST_JEDINICA *tekuci = *pglava;
125
126        while(tekuci->sledeci != NULL) {
127            tekuci = tekuci->sledeci;
128        }
129
130        tekuci->sledeci = novi;
131    }
132}
133
134unsigned ukupna_kvadratura(ST_JEDINICA *glava) {
135    ST_JEDINICA *tekuci = glava;
136    unsigned kvadratura_zgrade = 0;
137
138    while(tekuci != NULL) {
139        kvadratura_zgrade += tekuci->kvadratura_stana;
140        tekuci = tekuci->sledeci;
141    }
142
143    return kvadratura_zgrade;
144}
145
146void obrisi_listu(ST_JEDINICA **pglava) {
147    ST_JEDINICA *tmp;
148
149    while(*pglava != NULL) {
150        tmp = *pglava;
151        *pglava = (*pglava)->sledeci;
152        tmp->sledeci = NULL;
153        free(tmp);
154    }
155}
156
157double potrosnja_po_stanu(unsigned kv_stana, unsigned kv_zgrade, double ukupna_potrosnja) {
158    return (double) kv_stana / kv_zgrade * ukupna_potrosnja;
159}
160
161double uvecaj_za_porez(double osnovica, double procenat_pdv) {
162    return osnovica * (1 + procenat_pdv / 100);
163}
164