Prodavnica¶
Autor zadatka: Aleksandar Vasiljević <alexva02@uns.ac.rs>
Iz zadate ulazne datoteke artikli.txt
učitati podatke u jednostruko
spregnutu listu, gde struktura artikal_st
sadrži sledeća polja:
serijski_broj (ceo broj),
naziv (jedna reč, maksimalno 13 karaktera),
kolicina (pozitivan ceo broj),
jedinicna_cena (realan broj) i
ukupna_cena (realan broj).
Struktura artikal_st
, takođe sadrži i polja potrebna za pravilno
formiranje jednostruko spregnute liste. Prilikom formiranja jednostruko
spregnute liste voditi računa o tome da je potrebno elemente sortirati u
rastućem redosledu serijskog broja. Polje strukture ukupna_cena
izračunati na sledeći način: ukupna_cena = kolicina * jedinicna_cena
.
Potrebno je kupiti sve one artikle iz ponude prodavnice čiji zbir
ukupnih cena ne premašuje vrednost zadatog budžeta budzet
. Nakon
uspešne kupovine, ispisati sve informacije o svim kupljenim artiklima.
Uz to, ispisati još i iznos preostalog budžeta i informaciju o broju
kupljenih artikala. Ako se ispostavi da je budžet nedovoljan za kupovinu
bilo kog artikla iz ponude, ispisati odgovarajuću poruku i izaći iz
programa sa izlaznim kodom 333.
Ako se za vrednost argumenta komandne linije budzet
unese negativna
vrednost ispisati poruku o grešci i iz programa izaći sa izlaznim kodom
22.
Primer poziva:
./a.out 22800 artikli.txt
sa zadatim argumentom budzet = 22800
i zadatim ulazom u
datoteci artikli.txt
:
123.19 3 limun 2396
4399.99 25 trenerka 1179
109.11 8 tecni_sapun 7421
45.01 5 luk 7965
999.99 3 duks 4598
89.99 22 banane 8942
145.11 78 pasta_za_zube 1124
189.22 23 arf 3211
5899.39 7 pantalone 1698
215.49 13 ananas 1147
386.29 49 regenerator 3352
2354.99 15 farmerke 4452
i očekivanim ispisom na standardnom izlazu:
1124 pasta_za_zube 11318.58
1147 ananas 2801.37
2396 limun 369.57
3211 arf 4352.06
4598 duks 2999.97
7421 tecni_sapun 872.88
Uspesno ste kupili 6 proizvoda.
Na racunu vam je ostalo 85.57 din.
Ako se program pozove sa vrednošću budzet = -250
ispis treba da bude
sledeći:
Budzet mora biti pozitivan broj!
Ako se program pozove sa vrednošću budzet = 100
ispis treba da bude
sledeći:
Nemate dovoljno novca za kupovinu nijednog od proizvoda iz ponude!
Primer rešenja¶
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#define MAX_NAZIV 13+1
6
7typedef struct artikal_st {
8 int serijski_broj;
9 char naziv[MAX_NAZIV];
10 unsigned kolicina;
11 double jedinicna_cena;
12 double ukupna_cena;
13 struct artikal_st *sledeci;
14} ARTIKAL;
15
16void init_list(ARTIKAL **head) {
17 *head = NULL;
18}
19
20void add_to_list(ARTIKAL *new, ARTIKAL **head) {
21 ARTIKAL *tek,*pret1;
22 int nakraj=1;
23 if(*head == NULL) {
24 *head = new;
25 return;
26 }
27 pret1=*head;
28 tek=*head;
29
30 if(new->serijski_broj < tek->serijski_broj) {
31 new->sledeci=*head;
32 *head=new;
33 return;
34 }
35
36 while(tek != NULL) {
37 if(new->serijski_broj < tek->serijski_broj) {
38 nakraj=0;
39 break;
40 }
41 pret1=tek;
42 tek = tek->sledeci;
43 }
44
45 if(nakraj == 1) {
46 pret1 -> sledeci = new;
47 } else {
48 new->sledeci = pret1->sledeci;
49 pret1->sledeci = new;
50 }
51}
52
53ARTIKAL *create_new_item(int ser_br, char naz[], unsigned kol, double jed_c) {
54 ARTIKAL *new = (ARTIKAL *)malloc(sizeof(ARTIKAL));
55 if (new == NULL) {
56 printf("Not enough RAM!\n");
57 exit(21);
58 }
59 new->serijski_broj = ser_br;
60 strcpy(new->naziv, naz);
61 new->kolicina = kol;
62 new->jedinicna_cena = jed_c;
63 new->ukupna_cena = kol * jed_c;
64
65 new->sledeci = NULL;
66
67 return new;
68}
69
70void read_list_from(FILE *in, ARTIKAL **head) {
71 int tmpSerBr;
72 char tmpNaz[MAX_NAZIV];
73 unsigned tmpKol;
74 double tmpJedC;
75
76 while(fscanf(in,"%lf %u %s %d",&tmpJedC,&tmpKol,tmpNaz,&tmpSerBr) != EOF) {
77 ARTIKAL *new = create_new_item(tmpSerBr, tmpNaz, tmpKol, tmpJedC);
78 add_to_list(new, head);
79 }
80}
81
82void save_item_to(ARTIKAL *x) {
83 printf("\t%d %s %.2lf\n", x->serijski_broj, x->naziv, x->ukupna_cena);
84}
85
86void save_list_to(ARTIKAL *head) {
87 if(head != NULL) {
88 save_item_to(head);
89 save_list_to(head->sledeci);
90 }
91}
92
93void destroy_list(ARTIKAL **head) {
94 if(*head != NULL) {
95 destroy_list(&((*head)->sledeci));
96 free(*head);
97 *head = NULL;
98 }
99}
100
101void korpa(ARTIKAL * head,double budzet) {
102
103 int kupljeno=0;
104
105 if (head==NULL) {
106 return;
107 }
108
109 while(head != NULL) {
110 if(budzet-head->ukupna_cena >= 0) {
111 kupljeno++;
112 budzet-=head->ukupna_cena;
113 save_item_to(head);
114 }
115 head = head->sledeci;
116 }
117
118 if(kupljeno == 0) {
119 printf("Nemate dovoljno novca za kupovinu");
120 printf(" nijednog od proizvoda iz ponude!\n");
121 exit(333);
122 } else {
123 printf("\n\tUspesno ste kupili %d proizvoda.\n\t",kupljeno);
124 printf("Na racunu vam je ostalo %.2lf din.\n",budzet);
125 }
126}
127
128FILE *safe_fopen(char *filename, char *mode, int error_code) {
129 FILE *fp = fopen(filename, mode);
130 if (fp == NULL) {
131 printf("Can't open '%s'!\n", filename);
132 exit(error_code);
133 }
134 return fp;
135}
136
137
138//primer poziva ./a.out 22800 artikli.txt
139int main(int arg_num, char *args[]) {
140 if (arg_num != 3) {
141 printf("Pogresan unos argumenata\n");
142 exit(11);
143 }
144
145 if(atof(args[1]) < 0) {
146 printf("Budzet mora biti pozitivan broj!\n");
147 exit(22);
148 }
149
150 FILE *in = safe_fopen(args[2],"r", 1);
151
152 ARTIKAL *head;
153 init_list(&head);
154
155 read_list_from(in, &head);
156
157 korpa(head,atof(args[1]));
158
159 destroy_list(&head);
160
161 fclose(in);
162
163 return 0;
164}