Zadatak „Leti brzo, leti skupo”

Section author: Petar Marić <petarmaric@uns.ac.rs>

Ko leti - vredi,
ko vredi - leti,
ko ne leti - ne vredi.

—Otto Grunf

Iz zadate ulazne datoteke učitati statički niz struktura, pri čemu se struktura prevoznik_st sastoji od sledećih polja:

  • naziv operatera (jedna reč, do 20 karaktera)
  • cena karte (pozitivan realan broj)
  • maksimalna masa besplatnog prtljaga (pozitivan realan broj)
  • doplata za prekomerni prtljag po kilogramu (pozitivan realan broj)

Na osnovu zadate mase prtljaga masa (pozitivan realan broj) formirati novi statički niz struktura i upisati ga u zadatu izlaznu datoteku, pri čemu se struktura cena_st sastoji od sledećih polja:

  • ukupna cena leta (zaokružena na 2 decimale, koristiti "%7.2f" format specifikator)
  • naziv operatera (koristiti funkciju strcpy prilikom kopiranja iz strukture prevoznik_st)

Primer poziva:

./letovi 23.5 avioprevoznici.txt cene.txt

sa masa=23.5 i zadatim ulazom u datoteci avioprevoznici.txt:

JAT       150.0 2.5 1.5
Wizz       52.3 0.0 7.0
Lufthansa 210.0 7.0 2.5
Delta     180.0 6.5 1.0

i očekivanim izlazom u datoteci cene.txt:

181.50 JAT
216.80 Wizz
251.25 Lufthansa
197.00 Delta

Primer rešenja

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_NAZIV 20+1
#define MAX_NIZ 30

struct prevoznik_st {
    char operater[MAX_NAZIV];
    double cena_karte;
    double max_masa_besplatnog_prtljaga;
    double cena_po_kg;
};

struct cena_st {
    double ukupna_cena;
    char operater[MAX_NAZIV];
};


FILE *safe_fopen(char filename[], char mode[], int error_code);
void ucitaj_prevoznike(FILE *in, struct prevoznik_st prevoznici[], int *n);
double odredi_ukupnu_cenu(struct prevoznik_st prevoznik, double masa);
void transform(struct prevoznik_st prevoznici[], struct cena_st cene[], int n,
double masa);
void snimi_cene(FILE *out, struct cena_st cene[], int n);


int main(int arg_num, char **args) {
    if (arg_num != 4) {
        printf("USAGE: %s MASA IN_FILENAME OUT_FILENAME\n", args[0]);
        exit(42);
    }

    double masa = atof(args[1]);
    char *in_filename = args[2];
    char *out_filename = args[3];

    FILE *in  = safe_fopen(in_filename,  "r", 1);
    FILE *out = safe_fopen(out_filename, "w", 2);

    struct prevoznik_st prevoznici[MAX_NIZ];
    struct cena_st cene[MAX_NIZ];
    int n;

    ucitaj_prevoznike(in, prevoznici, &n);
    transform(prevoznici, cene, n, masa);
    snimi_cene(out, cene, n);

    fclose(in);
    fclose(out);

    return 0;
}

FILE *safe_fopen(char filename[], char mode[], int error_code) {
    FILE *fp = fopen(filename, mode);
    if(fp == NULL) {
        printf("Can't open '%s'!\n", filename);
        exit(error_code);
    }
    return fp;
}

void ucitaj_prevoznike(FILE *in, struct prevoznik_st prevoznici[], int *n) {
    *n = 0;
    while(fscanf(
        in, "%s %lf %lf %lf",
         prevoznici[*n].operater,
        &prevoznici[*n].cena_karte,
        &prevoznici[*n].max_masa_besplatnog_prtljaga,
        &prevoznici[*n].cena_po_kg
    ) != EOF) {
        (*n)++;
    }
}

double odredi_ukupnu_cenu(struct prevoznik_st prevoznik, double masa) {
    double base = prevoznik.cena_karte;

    double extra_masa = masa - prevoznik.max_masa_besplatnog_prtljaga;
    if (extra_masa > 0) {
        base += extra_masa * prevoznik.cena_po_kg;
    }

    return base;
}

void transform(struct prevoznik_st prevoznici[], struct cena_st cene[], int n,
double masa) {
    int i;
    for(i=0; i<n; i++) {
        strcpy(cene[i].operater, prevoznici[i].operater);

        cene[i].ukupna_cena = odredi_ukupnu_cenu(prevoznici[i], masa);
    }
}

void snimi_cene(FILE *out, struct cena_st cene[], int n) {
    int i;
    for(i=0; i<n; i++) {
        fprintf(
            out, "%7.2f %s\n",
            cene[i].ukupna_cena,
            cene[i].operater
        );
    }
}