#include #include #include #include #define STACK_SIZE 10 // struktura pre zasobniku; ma ako prvky array cisel s ciarou a aktualnu vel'kost. Pracuje an principe last in firts out struct stack{ float values[STACK_SIZE]; int size; }; struct stack mystack; //funkcia pre priadania cisla do zasobniku void push_stack(struct stack* stack, float value){ // ked' vel'kost zasobnika je vacsia ako size, program preruse assert(stack->size < STACK_SIZE); // -> operator pouzivame ked' pracujeme s pointermi // vlozienie cisla a zvacsenie vel'kosti stack->values[stack->size] = value; stack->size += 1; } /// funkcia aby zobrat' posldenie cislo float pop_stack(struct stack* stack){ // prerusi program ked' velkost' 0, nemozer nic zobrat' assert(stack->size > 0); //posledne cislo float value = stack->values[stack->size-1]; // zmensi velk'sot a vrati posledne cislo stack->size -= 1; return value; } // funkcia pre vypis void print_stack(struct stack* stack){ // jednoducho iterujeme po cislam zasobnika a vypisujeme nich podl'a podmienok for(int i = 0; i < stack->size; i++) printf("%.2f ", stack->values[i]); printf("\n"); } // funkcia pre operacii s kalculackou void process_operations(struct stack* stack) { // buffer pre nacitanie zo stdin char line[STACK_SIZE]; // premenna pre spracovanie; bude vzdy 1 ked' mame cislo alebo operaciu int could_read = 0; /// cyklus while prenacitanie; nacitujeme zo standartneho vstupu do buffery, ktory sme urcili while (fgets(line, sizeof(line), stdin)) { // mame nejaky vstup could_read= 1; // potrebujeme sa zbavit od novoho riadku pre spracovanie; odterminuejme na meste ho. Inak, ne budeme moct' porovnant' spravne pomocou strcmp line[strcspn(line, "\n")] = '\0'; // ked vstup whitespace - prerusi program a vypise no input if (line == '\0') {printf("no input\n"); return; } /// ked mame nejaku operaciu; strcmp porovnuje dva ret'azca a vrati 0 ked' su rovnake if ((strcmp(line, "+") == 0 || strcmp(line, "-") == 0 || strcmp(line, "*") == 0 || strcmp(line, "/") == 0)) { // ked' mame dostatny pocet operandov, tak zobrame ostatne dva cisla z zasobniku if (stack->size >= 2) { float last = pop_stack(stack); float second_last = pop_stack(stack); /// prerusime prgram a vypiseme chybu ked' mame podel' na 0 if (line[0] == '/' && last == 0.0F) { printf("division by zero\n"); return; } /// zlozene tverdenie pre vysldok operacii; v podstate je to kratsia versia niekolkych if tverzeni. // na zaciatku ide podmienka, potom ? operator, vysledok a : operator, ktory vysvetl;je co robit v inakom pripade // 0 tu ako keby defaultny pripad; nedojde do neho float res = (line[0] == '+') ? second_last + last : (line[0] == '-') ? second_last - last : (line[0] == '*') ? second_last * last : (line[0] == '/') ? second_last / last : 0; /// ked' operaciu podarilo urobit', pridame cislo do zasobniku a vypiseme zasobnik push_stack(stack, res); print_stack(stack); } // ked' v vasobniku je jedne cislo alebo nic, prerusime program a vypiseme chybu else { printf("not enough operands\n"); return; } // inak, skusame nacitat' vstup do zasobniku } else { /// nemozeme pridat' cislo do zasobniku ked' je plny if(stack->size == STACK_SIZE){ printf("full stack\n"); return; } // endpointer pre nacitanie pomocou strtof; char *endptr; // ked' format nie je spravny, prerusime a vypiseme chybu if (line[0] == '.') { printf("bad input\n"); return; } // skusame nacitat' vstup float val = strtof(line, &endptr); // v pripade ze nie je cislo prerusime a vypiseme chubu if (endptr == line) { printf("bad input\n"); return; } /// pridame cislo do zasobniku a vypiseme zasobnik podl'a podmienok push_stack(stack, val); print_stack(stack); } } // ked' nemame viac vstupov alebo nemali vstupov vobec vypiseme no input printf("no input\n"); } int main(void){ memset(&mystack,0,sizeof(struct stack)); process_operations(&mystack); }