Proizvodi u marketu

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

Proizvodi su opisani na sledeći način:

  • Naziv (jedna reč, maksimalno 20 karaktera)

  • vrsta (jedna reč, maksimalno 15 karaktera)

  • cena (realan broj)

Za proizvode iz ulazne datoteke uraditi sledeće:

  1. Učitati proizvode u jednostruko spregnutu listu. Novi elementi dodaju se tako da lista bude sortirana po ceni u rastućem redosledu.

  2. Na osnovu argumenta komandne linije koji označava vrstu proizvoda, na standardni izlaz (ekran Terminala) ispisati sledeće informacije:

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

  • naziv (ispisano sa %-12s format specifikatorom)

  • vrsta (ispisano sa %s format specifikatorom)

Ispisati da proizvodi ne postoje u slučaju da nijedan proizvod nije zadate vrste (pogledati primere ispisa programa).

Primer ulazne datoteke:

Deterdzent  149.99 hemija
Jaja         99.99 prehrambeni
Dezodorans  299.97 kozmetika
Secer        62.99 prehrambeni
KremaZaRuke 129.97 kozmetika
Brasno       49.97 prehrambeni
Prasak      429.90 hemija

Primer ispisa programa za postojeću zadatu vrstu proizvoda:

 49.97 Brasno       prehrambeni
 62.99 Secer        prehrambeni
 99.99 Jaja         prehrambeni

Primer poziva programa za postojeću zadatu vrstu proizvoda:

./proizvodi proizvodi.txt prehrambeni

Primer ispisa programa za nepostojeću zadatu vrstu proizvoda:

Ne postoji nijedan proizvod vrste odeca!

Primer poziva programa za nepostojeću zadatu vrstu proizvoda:

./proizvodi proizvodi.txt odeca

Primer rešenja

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