commit 5e55e32bf15da92092952ecbb85a59c99247de3c Author: Marto Date: Sun Jan 12 22:20:42 2025 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ff9047e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/cmake-build-debug/ diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/VerySimpleCalculator.iml b/.idea/VerySimpleCalculator.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/.idea/VerySimpleCalculator.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/editor.xml b/.idea/editor.xml new file mode 100644 index 0000000..226ca24 --- /dev/null +++ b/.idea/editor.xml @@ -0,0 +1,580 @@ + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..2c7451d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..fa5b23b --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..f8ffa7d --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..8e5f5ec --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.30) +project(VerySimpleCalculator C) + +set(CMAKE_C_STANDARD 23) + +add_executable(VerySimpleCalculator main.c) +target_link_libraries(VerySimpleCalculator m) \ No newline at end of file diff --git a/main.c b/main.c new file mode 100644 index 0000000..9aa9910 --- /dev/null +++ b/main.c @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include +#include + +typedef struct { + double first, second; + char op; +} CalcStr; + +CalcStr parse_input(int n, char *argv[]); +double parse_str_to_int(const char *str); +double calculate(CalcStr calc); +char* manipulate_str(double input); + +int main(const int argc, char *argv[]) { + const double res = calculate(parse_input(argc, argv)); + //manipulate string by cutting of trailing zeros + char* final_string = manipulate_str(res); + + printf("%s %s %s = %s", argv[1], argv[2], argv[3], final_string); + free(final_string); + return 0; +} + +CalcStr parse_input(const int n, char *argv[]) { + if (n < 4) { + perror("Insuficient arguments (3 are required), exiting"); + exit(EXIT_FAILURE); + } + + const CalcStr calc = {parse_str_to_int(argv[1]), parse_str_to_int(argv[3]), *argv[2]}; + return calc; +} + +double parse_str_to_int(const char *str) { + char *endptr; + errno = 0; + const double num = strtof(str, &endptr); + + if (errno == ERANGE || num < INT_MIN || num > INT_MAX) { + fprintf(stderr, "Input '%s' out of bounds\n", str); + exit(EXIT_FAILURE); + } + + if (endptr == str) { + fprintf(stderr, "No digits were found\n"); + } else if (*endptr != '\0') { + fprintf(stderr, "Invalid character '%c' in input '%s'\n", *endptr, str); + } else { + return num; + } + + // if parse fails then quit + exit(EXIT_FAILURE); +} + +double calculate(const CalcStr calc) { + switch (calc.op) { + case '+': + return calc.first + calc.second; + case '-': + return calc.first - calc.second; + case '*': + return calc.first * calc.second; + case '/': + return calc.first / calc.second; + case '^': + double r = 1; + for (int i = (int)calc.second; i > 0; i--) { + r *= calc.first; + } + + return r; + default: + perror("Invalid operand type"); + exit(EXIT_FAILURE); + } +} + +char* manipulate_str(const double input) { + const int str_basesize = (int)log10(input) + 16 + 1; + char *str = malloc(str_basesize * sizeof(char)); + if (str == nullptr) { + printf("Failed to allocate the memory"); + exit(EXIT_FAILURE); + } + memset(str, 0, str_basesize); + snprintf(str, str_basesize, "%f", input); + + char *ptr_to_zero = nullptr; + + // if it is check if the zeroes are trailing + for (char *i = str; *i != '\0'; i++) { + /* we will only show the last location where zeroes start + if ptr has been reset and we have stumbled upon a zero */ + if (*i == '0' && ptr_to_zero == nullptr) { + ptr_to_zero = i; + // reset the pointer if the following digit is no longer zero + } else if (*i != '0') { + ptr_to_zero = nullptr; + } + } + + // check if floating point is necessary at all + if (*(ptr_to_zero - 1) == '.') { + ptr_to_zero--; + } + + // clean the excess characters: ptr_to_zero is now the final char of the string + *ptr_to_zero = '\0'; + + return str; +} \ No newline at end of file