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}