126 lines
4.6 KiB
C
126 lines
4.6 KiB
C
#include <stdio.h>
|
|
#include<stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#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
|
|
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 b = pop_stack(stack);
|
|
float a = pop_stack(stack);
|
|
/// prerusime prgram a vypiseme chybu ked' mame podel' na 0
|
|
if (line[0] == '/' && b == 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] == '+') ? a + b :
|
|
(line[0] == '-') ? a - b :
|
|
(line[0] == '*') ? a * b :
|
|
(line[0] == '/') ? a / b : 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 vsupov vobec vypiseme no input
|
|
|
|
if (!could_read) {
|
|
printf("no input\n");
|
|
}
|
|
printf("no input\n");
|
|
}
|
|
int main(void){
|
|
memset(&mystack,0,sizeof(struct stack));
|
|
process_operations(&mystack);
|
|
} |