Pošiljke¶
Autor zadatka: Olja Anđelovski <andjelovski.olja@uns.ac.rs>
Iz zadate ulazne datoteke učitati podatke u jednostruko spregnutu listu.
Struktura paket se sastoji od sledećih polja:
oznaka paketa (jedna reč, do 8 karaktera)
osnovna cena (realan broj)
oznaka da li je paket isporučen (jedna reč, do 2 karaktera (moguće vrednosti da/ne))
udaljenost od glavne pošte (pozitivna, celobrojna vrednost)
Takođe, struktura paket sadrži i polja potrebna za pravilno formiranje jednostruko spregnute liste.
Preko argumenata komandne linije uneti naziv ulazne datoteke, naziv izlazne datoteke i maksimalnu udaljenost od glavne pošte.
U izlaznu datoteku ispisati sve pakete koji treba da se isporuče i izračunati konačnu cenu isporuke za svaki paket ponaosob. Konačna cena isporuke izavisi od maksimalne udaljenosti od glavne pošte.
Ukoliko je udaljenost paketa veća od maksimalne udaljenosti od glavne pošte, koju smo uneli preko argumenata komande linije, konačna cena isporuke se dobija tako što na osnovnu cenu doda polovina njene vrednosti.
Ukoliko je udaljenost paketa manja ili jednaka udaljenosti od glavne pošte, konačna cena isporuke se dobija tako što se na osnovnu cenu doda 50 din.
Obratiti pažnju na odgovarajuće rukovanje greškama pri radu sa datotekama (ne ispisivati ništa u datoteku niti standardni izlaz):
Ako nije moguće otvoriti ulaznu datoteku: izaći iz programa sa
exit(1)
Ako nije moguće otvoriti izlaznu datoteku: izaći iz programa sa
exit(2)
Primer poziva programa:
./a.out paketi.txt isporuka.txt 5
Zadati ulaz u datoteci paketi.txt
:
P1A152A1 450.50 da 4
P1A153A1 630.00 ne 4
P1A154A1 970.20 ne 9
P1A155A1 500.00 ne 7
P1A156A1 780.90 da 3
P1A157A1 890.60 ne 5
P1A158A1 960.00 ne 1
P1A158A1 640.00 ne 9
Izgled izlazne datoteke isporuka.txt sa izračunatom konačnom cenom isporuke isporuka.txt
:
P1A153A1 630.00 4, cena isporuke 680.00 din
P1A154A1 970.20 9, cena isporuke 1455.30 din
P1A155A1 500.00 7, cena isporuke 750.00 din
P1A157A1 890.60 5, cena isporuke 940.60 din
P1A158A1 960.00 1, cena isporuke 1010.00 din
P1A158A1 640.00 9, cena isporuke 960.00 din
Primer rešenja¶
1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4
5#define MAX_OZNAKA 9
6#define MAX_ISPORUCEN 3
7
8typedef struct paket{
9 char oznaka[MAX_OZNAKA];
10 float cena;
11 unsigned udaljenost;
12 char isporucen[MAX_ISPORUCEN];
13 struct paket *sledeci;
14} PAKET;
15
16void inicijalizacija(PAKET **);
17PAKET *napraviCvor(char *, float, int, char *);
18FILE *safeFopen(char *, char *, int);
19void ucitajStavke(FILE *, PAKET **);
20void dodajNaKraj(PAKET **, PAKET *);
21void izracunaj(FILE *, PAKET *, int);
22void obrisiListu(PAKET **);
23
24int main(int argc, char **argv) {
25 PAKET*glava;
26
27 if(argc != 4) {
28 printf("Primer poziva: %s paketi.txt isporuka.txt 5\n", argv[0]);
29 exit(EXIT_FAILURE);
30 }
31
32 inicijalizacija(&glava);
33
34 FILE *in = safeFopen(argv[1], "r", 1);
35 ucitajStavke(in, &glava);
36 fclose(in);
37
38 int maxUdaljenost = atoi(argv[3]);
39
40
41
42 FILE *out = safeFopen(argv[2], "w", 2);
43
44 izracunaj(out, glava, maxUdaljenost);
45
46 fclose(out);
47 obrisiListu(&glava);
48
49 return EXIT_SUCCESS;
50
51}
52
53FILE *safeFopen(char *name, char *mode, int errorCode) {
54 FILE *fp = fopen(name, mode);
55
56 if(fp == NULL) {
57 printf("Greska prilikom otvaranja fajla %s!\n", name);
58 exit(errorCode);
59 }
60
61 return fp;
62}
63
64void ucitajStavke(FILE *in, PAKET **glava) {
65 char oznaka[MAX_OZNAKA];
66 float cena;
67 int udaljenost;
68 char isporucen[MAX_ISPORUCEN];
69 PAKET *novi;
70
71 while(fscanf(in, "%s %f %s %u",
72 oznaka, &cena, isporucen, &udaljenost)
73 != EOF) {
74 novi = napraviCvor(
75 oznaka, cena, udaljenost, isporucen);
76 dodajNaKraj(glava, novi);
77 }
78}
79
80void izracunaj(FILE *out, PAKET *glava, int maxUdaljenost) {
81 PAKET *tekuci = glava;
82
83 while(tekuci != NULL) {
84 if(strcmp(tekuci->isporucen, "ne") == 0) {
85 if(tekuci->udaljenost <= maxUdaljenost){
86 fprintf(out, "%s %.2f %u, cena isporuke %.2f din\n", tekuci->oznaka, tekuci->cena, tekuci->udaljenost, tekuci->cena+50);
87 }
88 else {
89 fprintf(out, "%s %.2f %u, cena isporuke %.2f din\n", tekuci->oznaka, tekuci->cena, tekuci->udaljenost, tekuci->cena+(tekuci->cena/2));
90 }
91 }
92
93 tekuci = tekuci->sledeci;
94 }
95}
96
97void inicijalizacija(PAKET **glava) {
98 *glava = NULL;
99}
100
101PAKET *napraviCvor(char *oznaka, float cena, int udaljenost, char *isporucen) {
102 PAKET *novi = (PAKET *)malloc(sizeof(PAKET));
103
104 if(novi == NULL) {
105 printf("Nije moguce zauzeti memoriju!\n");
106 exit(EXIT_FAILURE);
107 }
108
109 strcpy(novi->oznaka, oznaka);
110 strcpy(novi->isporucen, isporucen);
111 novi->cena = cena;
112 novi->udaljenost = udaljenost;
113 novi->sledeci = NULL;
114
115 return novi;
116}
117
118void dodajNaKraj(PAKET **glava, PAKET *novi) {
119 if(*glava == NULL) {
120 *glava = novi;
121 } else {
122
123 PAKET *tekuci = *glava;
124 while(tekuci->sledeci != NULL) {
125 tekuci = tekuci->sledeci;
126 }
127 tekuci->sledeci = novi;
128 }
129}
130
131void obrisiListu(PAKET **glava) {
132 PAKET *tmp;
133
134 while(*glava != NULL) {
135 tmp = *glava;
136 *glava = (*glava)->sledeci;
137 tmp->sledeci = NULL;
138 free(tmp);
139 }
140}