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:
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