Untitled

mail@pastecode.io avatar
unknown
c_cpp
2 years ago
5.0 kB
0
Indexable
Never
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>

//Maximum array size
#define MAX 100

//Prototypes to create a Top-Down program
double       run_calculator(const bool*);
void         scan_data(char*, char*, double*);
double       do_next_op(char, double, double*);
bool         confirm_binary_operator(char);
bool         confirm_unary_operator(char);
void         split_string_by_space(char*, char*, double*);

//Mandatory variables
bool         runtime_status = true;
char         user_operator_input;
double       user_operand_input;
double       accumulator = 0.0;

//Operator arrays
const char   binary_operators[5] = {'+', '-', '*', '/', '^'};
const char   unary_operators[4]  = {'#', '%', '!', 'q'};

int main(void) {
    printf("Final result is: %lf", run_calculator(&runtime_status));
    return 0;
}

double run_calculator(const bool* runtime) {
    while (*runtime){
        char temp_input[MAX] = {0};

        printf("Enter operator, and an optional operand> ");
        fgets(temp_input, sizeof temp_input, stdin);

        if (strlen(temp_input) != 0){
            scan_data(temp_input, &user_operator_input, &user_operand_input);
            do_next_op(user_operator_input, user_operand_input, &accumulator);
        }

        if (*runtime)
            printf("Result so far is %lf\n", accumulator);
    }
    return accumulator;
}

void scan_data(char *user_input, char *operator_output, double *operand_output){

    char temp_operator;
    double temp_operand;

    split_string_by_space(user_input, &temp_operator, &temp_operand);

    bool temp_invalid_operator = (!confirm_binary_operator(temp_operator) && !confirm_unary_operator(temp_operator)) ? true : false;

    if (!temp_invalid_operator && confirm_unary_operator(temp_operator)){
        *operator_output = temp_operator;
        *operand_output = 0.0;
        return;

    }else if (!temp_invalid_operator && confirm_binary_operator(temp_operator) && operand_output != NULL){
        *operator_output = temp_operator;
        *operand_output = temp_operand;
        return;

    }else{
        return;
    }
}

double do_next_op(char operator_input, double operand_input, double *accumulator_variable){
        switch(operator_input){
            case '+':
                return (*accumulator_variable += operand_input);
            case '-':
                return (*accumulator_variable -= operand_input);
            case '*':
                return (*accumulator_variable *= operand_input);
            case '/':
                if (operand_input == 0)
                    break;
                return (*accumulator_variable /= operand_input);
            case '^':
                return (*accumulator_variable = pow(*accumulator_variable, operand_input));
            case '#':
                if (*accumulator_variable < 0)
                    break;
                return (*accumulator_variable = sqrt(*accumulator_variable));
            case '%':
                return (*accumulator_variable = -(*accumulator_variable));
            case '!':
                if (*accumulator_variable == 0)
                    break;
                return (*accumulator_variable = 1/(*accumulator_variable));
            case 'q':
                runtime_status = false;
                break;
            default:
                break;
        }
    return *accumulator_variable;
}

bool confirm_binary_operator(char operator){
    for (int i = 0; i < strlen(binary_operators); i++){
        if (binary_operators[i] == operator){
            return true;
        }
    }

    return false;
}

bool confirm_unary_operator(char operator){
    for (int i = 0; i < strlen(unary_operators); i++){
        if (unary_operators[i] == operator){
            return true;
        }
    }

    return false;
}

// https://www.w3resource.com/c-programming-exercises/string/c-string-exercise-31.php
// C Programming: Split string by space into words
void split_string_by_space(char *string, char *operator_output, double *operand_output){

    char *temp_ptr;
    char newString[MAX][MAX] = {0};
    int j = 0, ctr = 0;

    for(int i = 0; i <= strlen(string); i++)
    {
        //if space or NULL found, assign NULL into newString[ctr]
        if(string[i] == ' ' || string[i] == '\0')
        {
            newString[ctr][j] = '\0';
            ctr++;          //for next word
            j=0;            //for next word, init index to 0
        }
        else
        {
            newString[ctr][j] = string[i];
            j++;
        }
    }

    switch (ctr){
        case 1:
            *operator_output = *newString[0];
            break;
        case 2:
            *operator_output = *newString[0];
            *operand_output = strtod(newString[1], &temp_ptr);
            break;
        default:
            break;
    }
}