Pravo je vreme za kafu

Autor zadatka: Sanja Špica <sanjaspica@uns.ac.rs>

Iz zadate ulazne datoteke učitati podatke u jednostruko spregnutu listu, gde struktura kafa_st sadrži sledeća polja:

  • naziv kafića (jedna reč, do 20 karaktera)

  • vrsta kafe (jedna reč, do 20 karaktera)

  • cena kafe (pozitivan realan broj)

Naravno, struktura kafa_st sadrži i polja potrebna za pravilno formiranje jednostruko spregnute liste.

Na osnovu zadate vrste kafe vrsta_kafe iz formirane liste upisati podatke na standardni izlaz (terminal), u sledećem rasporedu polja strukture kafa_st:

  • cena (zaokružena na 2 decimale, koristiti "%6.2f" format specifikator)

  • naziv vrste kafe

  • naziv kafića

i potom u na standardni izlaz ispisati informaciju koja je prosečna cena zadate vrste kafe (zaokružena na 2 decimale, koristiti "%6.2f" format specifikator).

Primer poziva programa:

./kafica Espresso kafa.txt

sa vrsta_kafe=Espresso i zadatim ulazom u datoteci kafa.txt:

Caffe_City  Espresso   105.00
Caffe_City  Macchiato  135.00
Caffe_City  Cappuccino 145.00
Caffe_Solo  Espresso   140.00
Caffe_Solo  Macchiato  150.00
Caffe_Solo  Cappuccino 160.00
Caffe_Style Espresso   173.00
Caffe_Style Macchiato  195.00
Caffe_Style Cappuccino 215.00

i očekivanim izlazom

105.00 Espresso   Caffe_City
135.00 Macchiato  Caffe_City
145.00 Cappuccino Caffe_City
140.00 Espresso   Caffe_Solo
150.00 Macchiato  Caffe_Solo
160.00 Cappuccino Caffe_Solo
173.00 Espresso   Caffe_Style
195.00 Macchiato  Caffe_Style
215.00 Cappuccino Caffe_Style

Prosecna cena Espresso kafe je = 139.33

sa vrsta_kafe=Latte:

Latte kafa nije u ponudi!

Primer rešenja

  1#include <stdio.h>
  2#include <stdlib.h>
  3#include <string.h>
  4
  5#define MAX_CAFFE 20 + 1
  6#define MAX_VRSTA_KAFE 20 + 1
  7
  8typedef struct kafa_st
  9{
 10  char caffe[MAX_CAFFE];
 11  char vrsta_kafe[MAX_VRSTA_KAFE];
 12  double cena;
 13
 14  struct kafa_st *sledeci;
 15} KAFA;
 16
 17FILE *safe_fopen(char *filename, char *mode);
 18void ucitaj(FILE *in, KAFA **glava);
 19void inicijalizacija(KAFA **glava);
 20KAFA *napravi_cvor(char *caffe, char *vrsta_kafe, double *cena);
 21void dodaj_cvor(KAFA **glava, KAFA *novi);
 22double prosek(KAFA *glava, char vrsta_kafe[]);
 23void ispis(KAFA *glava);
 24void obrisi_listu(KAFA **glava);
 25
 26int main(int BrArg, char **argv)
 27{
 28  if (BrArg != 3)
 29  {
 30    printf("Greska prilikom poziva programa\n");
 31    exit(EXIT_FAILURE);
 32  }
 33
 34  char *vrsta_kafe = argv[1];
 35  FILE *in = safe_fopen(argv[2], "r");
 36  KAFA *glava;
 37
 38  inicijalizacija(&glava);
 39
 40  ucitaj(in, &glava);
 41  ispis(glava);
 42
 43  double prosecna_cena = prosek(glava, vrsta_kafe);
 44  if (prosecna_cena == 0)
 45  {
 46    printf("\n%s kafa nije u ponudi!\n", vrsta_kafe);
 47  }
 48  else
 49  {
 50    printf(
 51        "\nProsecna cena %s kafe je = %6.2lf\n",
 52        vrsta_kafe, prosecna_cena);
 53  }
 54  obrisi_listu(&glava);
 55
 56  fclose(in);
 57
 58  return 0;
 59}
 60FILE *safe_fopen(char *filename, char *mode)
 61{
 62  FILE *fp = fopen(filename, mode);
 63
 64  if (fp == NULL)
 65  {
 66    printf("Nije moguce otvoriti datoteku %s!\n", filename);
 67    exit(EXIT_FAILURE);
 68  }
 69
 70  return fp;
 71}
 72
 73void ucitaj(FILE *in, KAFA **glava)
 74{
 75  char caffe[MAX_CAFFE];
 76  char vrsta_kafe[MAX_VRSTA_KAFE];
 77  double cena;
 78
 79  while (fscanf(in, "%s %s %lf", caffe, vrsta_kafe, &cena) != EOF)
 80  {
 81    dodaj_cvor(glava, napravi_cvor(caffe, vrsta_kafe, &cena));
 82  }
 83}
 84void inicijalizacija(KAFA **glava)
 85{
 86  *glava = NULL;
 87}
 88KAFA *napravi_cvor(char *caffe, char *vrsta_kafe, double *cena)
 89{
 90  KAFA *novi = (KAFA *)malloc(sizeof(KAFA));
 91
 92  if (novi == NULL)
 93  {
 94    printf("Greska prilikom zauzimanja memorije!\n");
 95    exit(EXIT_FAILURE);
 96  }
 97  strcpy(novi->caffe, caffe);
 98  strcpy(novi->vrsta_kafe, vrsta_kafe);
 99  novi->cena = *cena;
100
101  novi->sledeci = NULL;
102
103  return novi;
104}
105void dodaj_cvor(KAFA **glava, KAFA *novi)
106{
107  if (*glava == NULL)
108  {
109    *glava = novi;
110  }
111  else
112  {
113    KAFA *tekuci = *glava;
114
115    while (tekuci->sledeci != NULL)
116    {
117      tekuci = tekuci->sledeci;
118    }
119
120    tekuci->sledeci = novi;
121  }
122}
123int broj_kafe(KAFA *glava, char vrsta_kafe[])
124{
125  int brojac = 0;
126
127  while (glava != NULL)
128  {
129    if (strcmp(glava->vrsta_kafe, vrsta_kafe) == 0)
130    {
131      brojac++;
132    }
133    glava = glava->sledeci;
134  }
135  return brojac;
136}
137
138double suma_kafa(KAFA *glava, char vrsta_kafe[])
139{
140  double suma = 0;
141
142  while (glava != NULL)
143  {
144    if (strcmp(glava->vrsta_kafe, vrsta_kafe) == 0)
145    {
146      suma += glava->cena;
147    }
148    glava = glava->sledeci;
149  }
150  return suma;
151}
152double prosek(KAFA *glava, char vrsta_kafe[])
153{
154  int brojac = broj_kafe(glava, vrsta_kafe);
155  if (brojac == 0)
156  {
157    return 0;
158  }
159  else
160  {
161    return suma_kafa(glava, vrsta_kafe) / brojac;
162  }
163}
164void ispis(KAFA *glava)
165{
166  KAFA *tekuci = glava;
167
168  while (tekuci != NULL)
169  {
170    printf(
171        "%6.2lf %s %s\n",
172        tekuci->cena,
173        tekuci->vrsta_kafe,
174        tekuci->caffe);
175    tekuci = tekuci->sledeci;
176  }
177}
178void obrisi_listu(KAFA **glava)
179{
180  KAFA *tekuci;
181
182  while (*glava != NULL)
183  {
184    tekuci = *glava;
185    *glava = (*glava)->sledeci;
186    tekuci->sledeci = NULL;
187    free(tekuci);
188  }
189}