Magacin mobilne i računarske opreme

Autor zadatka: Olja Anđelovski <andjelovski.olja@uns.ac.rs>

Iz zadate ulazne datoteke učitati podatke u jednostruko spregnutu listu. Podatke učitati u rastućem redosledu po šifri magacina.

Struktura magacin sadrži sledeća polja:

  • šifra magacina (pozitivna celobrojna vrednost)

  • šifra proizvoda (pozitivna celobrojna vrednost)

  • naziv proizvoda (jedna reč, do 9 karaktera)

  • cena (pozitivna celobrojna vrednost)

Takođe, struktura magacin sadrži i polja potrebna za pravilno formiranje jednostruko spregnute liste.

Na terminal ispisati sve podatke iz ulazne datoteke. Potom od korisnika zatražiti da unese šifru magacina (pozitivna celobrojna vrednost) i šifru proizvoda (pozitivna celobrojna vrednost, poogledati stavku 3.). Za unete podatke na terminal ispisati šifru magacina, šifru proizvoda, ukupnu količinu i vrednost proizvoda (ispoštovati očekivani izlaz prikazan u stavci pod rednim brojem 4.).

Napomene:

  • Kroz argumente komandne linije proslediti naziv ulazne datoteke.

  • Ukoliko za unete podatke od strane korisnika ne postoje podaci očekivan izlaz je prikazan u stavci pod rednim brojem 5.

  1. Primer poziva:

    ./a.out magacin.txt
    
  2. Zadati ulaz u datoteci magacin.txt:

123 11 maskica 900
251 75 punjac 300
954 30 kamera 1520
251 75 punjac 750
123 11 maskica 900
123 77 mis 1100
123 99 slusalice 470
251 78 baterija 230
  1. Ispis podataka na terminal i unos šifre magacina i šifre proizvoda preko terminala:

    123 11 maskica 900
    123 99 slusalice 470
    123 77 mis 1100
    123 11 maskica 900
    251 78 baterija 230
    251 75 punjac 750
    251 75 punjac 300
    954 30 kamera 1520
    
    Unesite sifru magacina: 123
    Unesite sifru proizvoda: 11
    
  2. Očekivani izlaz na terminal ukoliko postoje magacin i proizvod:

    Ukupno proizvoda sa sifrom 11, pod nazivom maskica u magacinu sa sifrom 123 ima 2.
    Ukupna vrednost proizvoda je 1800 dinara.
    
  3. Očekivani izlaz na terminal ukoliko ne postoje magacin i proizvod:

    Za unete podatke od strane korisnika ne postoje podaci.
    

Primer rešenja

  1#include <stdio.h>
  2#include <stdlib.h>
  3#include <string.h>
  4
  5#define MAX_NAZIV 10
  6
  7typedef struct magacin {
  8    unsigned sifraMagacina;
  9    unsigned sifraProizvoda;
 10    char nazivProizvoda[MAX_NAZIV];
 11    unsigned cena;
 12    struct magacin *next;
 13}MAGACIN;
 14
 15void init_list(MAGACIN **head) {
 16    *head = NULL;
 17}
 18
 19void add_to_list(MAGACIN *new, MAGACIN **head) {
 20    if(*head == NULL) { 
 21        *head = new;
 22        return;
 23    } 
 24 
 25    if((*head)->sifraMagacina > new->sifraMagacina) {
 26        new->next = *head;
 27        *head = new;
 28    } else {
 29        MAGACIN* tek = *head;
 30        MAGACIN* pret = *head;
 31        while(tek != NULL && tek->sifraMagacina < new->sifraMagacina) {
 32            pret = tek;
 33            tek = tek->next;
 34        }
 35        new -> next = pret -> next;
 36        pret -> next = new;
 37    }  
 38}
 39
 40void print(MAGACIN *head){
 41    if (head == NULL) { 
 42        return;
 43    }
 44
 45    while(head != NULL) {
 46        printf("\n%d %d %s %d", head->sifraMagacina, 
 47        head->sifraProizvoda, 
 48        head->nazivProizvoda, head->cena);
 49        head = head->next;
 50    }
 51}
 52
 53MAGACIN *create_new_item(unsigned sifraMagacina, 
 54unsigned sifraProizvoda, char nazivProizvoda[], unsigned cena) {
 55    MAGACIN *new = (MAGACIN*)malloc(sizeof(MAGACIN));
 56    if (new == NULL) {
 57        printf("Not enough RAM!\n");
 58        exit(21);
 59    }
 60
 61    new->sifraMagacina = sifraMagacina;
 62    new->sifraProizvoda = sifraProizvoda;
 63    strcpy(new->nazivProizvoda, nazivProizvoda);
 64    new->cena = cena;
 65
 66    new->next = NULL;
 67
 68    return new;
 69}
 70
 71void read_list_from(FILE *in, MAGACIN **head) {
 72    unsigned sifraMagacina;
 73    unsigned sifraProizvoda;
 74    char nazivProizvoda[MAX_NAZIV];
 75    unsigned cena;
 76    
 77    while(fscanf(in, "%u %u %s %u", &sifraMagacina,
 78    &sifraProizvoda, nazivProizvoda, &cena) != EOF) {
 79        MAGACIN *new = create_new_item(sifraMagacina,
 80        sifraProizvoda, nazivProizvoda, cena);
 81        add_to_list(new, head);
 82    }
 83}
 84
 85void save_item_to(int postoji, char nazivProizvoda[], unsigned sifraMagacina,
 86unsigned sifraProizvoda, unsigned ukupnaVrednost, unsigned brojProizvoda) {
 87
 88    if(postoji==1){
 89        printf("\nUkupno proizvoda sa sifrom %u, "
 90        "pod nazivom %s u magacinu sa sifrom %u ima "
 91        "%u.\nUkupna vrednost proizvoda je %u dinara.", 
 92            sifraProizvoda, nazivProizvoda,
 93            sifraMagacina, brojProizvoda, ukupnaVrednost);
 94    }
 95    else{
 96        printf("\nNe postoji magacin i proizvod za unete podatke.");
 97    }
 98}
 99
100void destroy_list(MAGACIN **head) {
101    if(*head != NULL) {
102        destroy_list(&((*head)->next));
103        free(*head);
104        *head = NULL;
105    }
106}
107
108FILE *safe_fopen(char *filename, char *mode, int error_code) {
109    FILE *fp = fopen(filename, mode);
110    if (fp == NULL) {
111        printf("Nije moguce otvoriti datoteku '%s'!\n", filename);
112        exit(error_code);
113    }
114    return fp;
115}
116
117void algoritam(MAGACIN *head, unsigned sm, unsigned sp){
118    unsigned brojProizvoda = 0;
119    unsigned ukupnaVrednost = 0;
120    char nazivProizvoda[MAX_NAZIV];
121    int postoji=0;
122
123    if (head == NULL) { 
124        return;    
125    }
126    
127    while(head != NULL) {      
128        if (head->sifraMagacina==sm && head->sifraProizvoda==sp) {
129            postoji=1;
130            strcpy(nazivProizvoda, head->nazivProizvoda);
131            ukupnaVrednost += head->cena;
132            brojProizvoda++;
133        }    
134        head = head->next;
135    }
136    save_item_to(postoji, nazivProizvoda, sm,
137    sp, ukupnaVrednost, brojProizvoda);
138}
139
140int main(int arg_num, char *args[]) {
141    if (arg_num != 2) {
142        printf("Program treba pozvati na sledeci nacin:"
143        "%s nazivUlazneDatoteke.txt\n", args[0]);
144        exit(11);
145    }
146
147    char *in_filename = args[1];
148
149    FILE *in  = safe_fopen(in_filename,  "r", 1);
150
151    unsigned sifraMagacina, sifraProizvoda;
152
153    MAGACIN *head;
154    init_list(&head);
155    read_list_from(in, &head);
156    print(head);
157    
158    printf("\n\nUnesite sifru magacina: ");
159    scanf("%u", &sifraMagacina);
160    printf("Unesite sifru proizovoda: ");
161    scanf("%u", &sifraProizvoda);
162
163    algoritam(head, sifraMagacina, sifraProizvoda);
164    destroy_list(&head);
165
166    fclose(in);
167
168    return 0;
169}