Slanje paketa kurirskom službom

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

Paketi su opisani na sledeći način:

  • sadržaj (jedna reč, maksimalno 30 karaktera)

  • masa (realna vrednost, u kilogramima)

  • lomljivo (jedna reč, "DA", ili "NE", maksimalno 2 karaktera)

Paketi se šalju putem kurirske službe, koja naplaćuje usluge slanja paketa u odnosu na njegovu masu. Učitati pakete u jednostruko spregnutu listu (dodati novi element na kraj liste) i uraditi sledeće:

  1. Izračunati cenu dostave paketa na osnovu sledećeg cenovnika:

Masa [kg]

Cena

0-5

200

5-10

400

Ukoliko paket ima više od 10kg, dodatna masa paketa se naplaćuje pomnožena sa vrednošću argumenta komandne linije, koji predstavlja cenu po kilogramu.

  1. Na standardni izlaz (ekran Terminala) ispisati sledeće informacije:

  • sadržaj (ispisano sa %-10s format specifikatorom)

  • lomljivo (ispisano sa %2s format specifikatorom)

  • cena (zaokruženo na dve decimale, ispisano sa %6.2lf format specifikatorom)

Primer ulazne datoteke:

Tanjiri  3.2 DA
Igracka  2.1 NE
Stolica 14.6 NE
Laptop   5.4 DA
Sto     23.7 NE
Monitor  4.2 DA

Primer ispisa programa:

Tanjiri    DA 200.00
Igracka    NE 200.00
Stolica    NE 425.30
Laptop     DA 400.00
Sto        NE 475.35
Monitor    DA 200.00

Primer poziva programa:

./paketi paketi.txt 5.5

Primer rešenja

  1#include <stdio.h>
  2#include <string.h>
  3#include <stdlib.h>
  4
  5#define MAX_SADRZAJ 31
  6#define MAX_LOMLJIVO 3
  7
  8typedef struct paket_st {
  9  char sadrzaj[MAX_SADRZAJ];
 10  double masa;
 11  char lomljivo[MAX_LOMLJIVO];
 12  struct paket_st *sledeci;
 13} PAKET;
 14
 15FILE *safe_fopen(char *filename, char *mode);
 16void ucitaj(FILE *ulazna, PAKET **pglava);
 17void ispisi_cene_dostave(PAKET *glava, double dodatno_po_kg);
 18
 19void inicijalizacija(PAKET **pglava);
 20PAKET *napravi_cvor(char *sadrzaj, double masa, char *lomljivo);
 21void dodaj_cvor(PAKET **pglava, PAKET *novi);
 22void obrisi_listu(PAKET **pglava);
 23
 24int main(int argc, char **argv) {
 25    if(argc != 3) {
 26        printf("Primer poziva: %s paketi.txt 5.5\n", argv[0]);
 27        exit(EXIT_FAILURE);
 28    }
 29
 30    FILE *ulazna = safe_fopen(argv[1], "r");
 31    PAKET *glava;
 32    double dodatno_po_kg = atof(argv[2]);
 33
 34    inicijalizacija(&glava);
 35
 36    ucitaj(ulazna, &glava);
 37    ispisi_cene_dostave(glava, dodatno_po_kg);
 38
 39    obrisi_listu(&glava);
 40
 41    fclose(ulazna);
 42
 43    return EXIT_SUCCESS;
 44}
 45
 46FILE *safe_fopen(char *filename, char *mode) {
 47    FILE *fp = fopen(filename, mode);
 48
 49    if(fp == NULL) {
 50        printf("Nije moguce otvoriti datoteku %s!\n", filename);
 51        exit(EXIT_FAILURE);
 52    }
 53
 54    return fp;
 55}
 56
 57void ucitaj(FILE *ulazna, PAKET **pglava) {
 58    char sadrzaj[MAX_SADRZAJ];
 59    double masa;
 60    char lomljivo[MAX_LOMLJIVO];
 61
 62    while(fscanf(ulazna, "%s %lf %s", sadrzaj, &masa, lomljivo) != EOF) {
 63        dodaj_cvor(pglava, napravi_cvor(sadrzaj, masa, lomljivo));
 64    }
 65}
 66
 67void ispisi_cene_dostave(PAKET *glava, double dodatno_po_kg) {
 68    PAKET *tekuci = glava;
 69
 70    while(tekuci != NULL) {
 71        double cena;
 72
 73        if(tekuci->masa > 0 && tekuci->masa <= 5) {
 74            cena = 200;
 75        } else if(tekuci->masa > 5 && tekuci->masa <= 10) {
 76            cena = 400;
 77        } else if(tekuci->masa > 10) {
 78            cena = 400 + (tekuci->masa - 10) * dodatno_po_kg;
 79        }
 80
 81        printf("%-10s %2s %5.2lf\n", tekuci->sadrzaj, tekuci->lomljivo, cena);
 82        tekuci = tekuci->sledeci;
 83    }
 84}
 85
 86void inicijalizacija(PAKET **pglava) {
 87    *pglava = NULL;
 88}
 89
 90PAKET *napravi_cvor(char *sadrzaj, double masa, char *lomljivo) {
 91    PAKET *novi = (PAKET *)malloc(sizeof(PAKET));
 92
 93    if(novi == NULL) {
 94        printf("Greska prilikom zauzimanja memorije!\n");
 95        exit(EXIT_FAILURE);
 96    }
 97
 98    strcpy(novi->sadrzaj, sadrzaj);
 99    novi->masa = masa;
100    strcpy(novi->lomljivo, lomljivo);
101    novi->sledeci = NULL;
102
103    return novi;
104}
105
106void dodaj_cvor(PAKET **pglava, PAKET *novi) {
107    if(*pglava == NULL) {
108        *pglava = novi;
109    } else {
110        PAKET *tekuci = *pglava;
111
112        while(tekuci->sledeci != NULL) {
113            tekuci = tekuci->sledeci;
114        }
115
116        tekuci->sledeci = novi;
117    }
118}
119
120void obrisi_listu(PAKET **pglava) {
121    PAKET *tmp; 
122
123    while(*pglava != NULL) {
124       tmp = *pglava;
125       *pglava = (*pglava)->sledeci; 
126       tmp->sledeci = NULL;
127       free(tmp);
128    }
129}
130