Skip to content

Instantly share code, notes, and snippets.

@gfreivasc
Last active February 24, 2020 18:13
Show Gist options
  • Save gfreivasc/cbe1ea5b00113cfb5eb416f166f29c71 to your computer and use it in GitHub Desktop.
Save gfreivasc/cbe1ea5b00113cfb5eb416f166f29c71 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/// --- STACK DEFINITION ---
typedef struct node_ {
int value;
struct node_* last;
} stack_node_t;
typedef struct {
stack_node_t* top;
} _stack_t;
void push(_stack_t* stack, const int value) {
stack_node_t* new = malloc(sizeof(stack_node_t));
new->value = value;
new->last = stack->top;
stack->top = new;
}
int pop(_stack_t* stack) {
if (stack->top == NULL) return 0;
stack_node_t* popped = stack->top;
int value = popped->value;
stack->top = popped->last;
free(popped);
return value;
}
int size(const _stack_t* stack) {
stack_node_t* iter = stack->top;
int count = 0;
while (iter != NULL) {
count++;
iter = iter->last;
}
return count;
}
int empty(const _stack_t* stack) {
return stack->top == NULL ? 1 : 0;
}
_stack_t* create() {
_stack_t* created = malloc(sizeof(_stack_t));
created->top = NULL;
return created;
}
/// --- END OF STACK DEFINITION ---
/// --- STRING HELPERS ---
int isDigit(char c) {
return (c >= '0' && c <= '9') ? 1 : 0;
}
int isInteger(const char* str) {
int allDigits = 1;
int len = strlen(str);
char first = str[0];
if (len > 1) {
allDigits = (first == '-' || isDigit(first)) ? 1 : 0;
if (allDigits) {
int i = 1;
for (; str[i]; ++i) {
if (!isDigit(str[i])) {
allDigits = 0;
break;
}
}
}
} else {
allDigits = isDigit(first);
}
return allDigits;
}
int isOperation(const char* str) {
return strlen(str) == 1 && (
str[0] == '+' || str[0] == '-' || str[0] == '*' || str[0] == '/'
);
}
/// --- END OF STRING HELPERS ---
int parseOperation(const char op, _stack_t* stack);
int operate(const char op, const int left, const int right);
int main() {
_stack_t* stack = create();
char input[16] = "";
printf("Digite inicie a operação (s para sair):\n");
while (input[0] != 's') {
scanf(" %15s", input);
if (isInteger(input)) {
push(stack, atoi(input));
} else if (isOperation(input)) {
int current = parseOperation(input[0], stack);
if (size(stack) > 0) {
printf("> %d\n", current);
} else {
printf(">> %d\n", current);
}
push(stack, current);
}
}
return 0;
}
int parseOperation(const char op, _stack_t* stack) {
int result = empty(stack) ? 0 : pop(stack);
if (!empty(stack)) {
result = operate(op, pop(stack), result);
}
return result;
}
int operate(const char op, const int left, const int right) {
switch (op) {
case '+': return left + right;
case '-': return left - right;
case '*': return left * right;
case '/': {
if (right == 0) {
printf("ERR: Cannot divide by 0\n");
return left;
}
return left / right;
}
default: return left;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment