Untitled
unknown
c_cpp
3 years ago
5.0 kB
3
Indexable
#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;
}
}Editor is loading...