usaa25/du3/program.c
2025-10-07 11:00:07 +02:00

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);
}