{"id":11128,"date":"2026-01-25T23:20:06","date_gmt":"2026-01-25T21:20:06","guid":{"rendered":"https:\/\/blue.pri.ee\/ttu\/?page_id=11128"},"modified":"2026-06-19T15:20:04","modified_gmt":"2026-06-19T13:20:04","slug":"loendite-naide-kasurea-kalkulaatori-pohjal","status":"publish","type":"page","link":"https:\/\/blue.pri.ee\/ttu\/programmeerimine-ii\/koodinaited\/loendite-naide-kasurea-kalkulaatori-pohjal\/","title":{"rendered":"Loendite ja p\u00e4isefaili n\u00e4ide k\u00e4surea kalkulaatori p\u00f5hjal"},"content":{"rendered":"<p>J\u00e4rgneva n\u00e4ite eesm\u00e4rk on tutvustada loendite (<span class=\"lang:c highlight:0 decode:true crayon-inline \">enum<\/span> ) deklareerimist ning kasutamist programmiga, mis on juba Programmeerimine 1 raames tuttav. N\u00e4ites on loodud kolm loendit<\/p>\n<ol>\n<li>K\u00e4sureaargumentide kirjeldamiseks<\/li>\n<li>Veakoodide kodeerimiseks<\/li>\n<li>Matemaatiliste operatsioonide kodeerimiseks<\/li>\n<\/ol>\n<p>N\u00e4itest on loodud kolm varianti, mis k\u00f5ik vastavad erinevatele teadmiste astmele erinevatel hetkedel kursusel<\/p>\n<ol>\n<li><strong>Baaslahendus<\/strong> on sobilik <strong>n\u00e4dalal 2<\/strong>. See rakendab vaid loendeid.<\/li>\n<li><strong>Struktuuridega lahendus<\/strong> on sobilil <strong>n\u00e4dalal 3<\/strong>. Seal lisame juurde n\u00f6 vastendustabeli, kus seome \u00e4ra tehete t\u00e4hem\u00e4rgid ning sellele vastava loendi v\u00e4\u00e4rtuse algv\u00e4\u00e4rtustatud struktuuride massiivis, millest on mugav ts\u00fckliga \u00fcle k\u00e4ia.<\/li>\n<li><strong>P\u00e4isefailiga lahendus<\/strong> on sobilik <strong>n\u00e4dalal 4<\/strong>. Seal v\u00f5tame eelmise lahenduse ning t\u00fckeldame selle kahte faili &#8211; p\u00e4ise ja koodifail. See on \u00fchtlasi ka v\u00f5rdlemisi l\u00e4hedane kodut\u00f6\u00f6 1 n\u00f5uetele vastavale koodile.<\/li>\n<\/ol>\n<div class=\"su-tabs su-tabs-style-default su-tabs-mobile-stack\" data-active=\"1\" data-scroll-offset=\"0\" data-anchor-in-url=\"yes\"><div class=\"su-tabs-nav\"><span class=\"\" data-url=\"\" data-target=\"blank\" tabindex=\"0\" role=\"button\">Baaslahendus<\/span><span class=\"\" data-url=\"\" data-target=\"blank\" tabindex=\"0\" role=\"button\">Struktuuridega lahendus<\/span><span class=\"\" data-url=\"\" data-target=\"blank\" tabindex=\"0\" role=\"button\">P\u00e4isefailiga lahendus<\/span><\/div><div class=\"su-tabs-panes\"><div class=\"su-tabs-pane su-u-clearfix su-u-trim\" data-title=\"Baaslahendus\">\n<pre class=\"lang:c decode:true \">\/**\r\n * File:        calc_enum.c\r\n * Author:      Risto Heinsar\r\n * Created:     25.01.2026\r\n * Edited:      19.06.2026\r\n *\r\n * Description: Example program that's based on Programming 1 calculator lab.\r\n *              Introduces simple use cases for enum type.\r\n *\/\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;ctype.h&gt;\r\n#include &lt;string.h&gt;\r\n\r\n#define DEBUG 0\r\n\r\n#define ARGS_CNT_EXPECTED 4\r\n\r\nenum ArgsPosition { ARGS_EXEC, ARGS_OPERAND_1, ARGS_OPERATION, ARGS_OPERAND_2 };\r\nenum MathOperation { OP_ADD, OP_SUB, OP_MULT, OP_DIV, OP_UNKNOWN };\r\n\r\nenum ErrorCode\r\n{\r\n    ERR_ARG_CNT = 0,\r\n    ERR_UNRECOGNIZED_ARG,\r\n    ERR_OPERATION_INVALID,\r\n    ERR_OPERAND_MULT_SEPARATOR,\r\n    ERR_OPERAND_UNKNOWN_SYMBOL,\r\n    ERR_DIV_ZERO\r\n};\r\n\r\n\r\ndouble Calculate(double val1, double val2, enum MathOperation op);\r\nvoid ErrorHandler(enum ErrorCode code);\r\nvoid DebugArgs(int argc, char **argv);\r\ndouble EvalOperand(const char *operand);\r\nenum MathOperation GetOperation(const char *op);\r\nvoid Usage(void);\r\nvoid CheckArgs(int argc, char **argv);\r\n\r\n\/\/ Contains argv[0] to print exec path in Usage() for guidance \r\nconst char *execName;\r\n\r\nint main(int argc, char **argv)\r\n{\r\n    execName = argv[ARGS_EXEC];\r\n\r\n    CheckArgs(argc, argv);\r\n    \r\n    if (DEBUG) DebugArgs(argc, argv);\r\n\r\n    double val1 = EvalOperand(argv[ARGS_OPERAND_1]);\r\n    double val2 = EvalOperand(argv[ARGS_OPERAND_2]);\r\n\r\n    enum MathOperation op = GetOperation(argv[ARGS_OPERATION]);\r\n\r\n    printf(\"&gt; %.2f\\n\", Calculate(val1, val2, op));\r\n\r\n    return EXIT_SUCCESS;\r\n}\r\n\r\n\/**\r\n * Description:   Calculates the mathematical equation and returns the answer\r\n * \r\n * Parameters:    val1 - first operand\r\n *                val2 - second operand\r\n *                op - mathematical operation coded value\r\n * \r\n * Return:        result of the mathematical operation\r\n *\/\r\ndouble Calculate(double val1, double val2, enum MathOperation op)\r\n{\r\n    \/\/ Note: all cases either return or exit using ErrorHandler()\r\n    switch (op)\r\n    {\r\n        case OP_ADD:\r\n            return val1 + val2;\r\n        case OP_SUB:\r\n            return val1 - val2;\r\n        case OP_MULT:\r\n            return val1 * val2;\r\n        case OP_DIV:\r\n            if (val2 == 0)\r\n                ErrorHandler(ERR_DIV_ZERO);\r\n                \r\n            return val1 \/ val2;\r\n        default:\r\n            ErrorHandler(ERR_OPERATION_INVALID);\r\n    }\r\n    \r\n    \/\/ This should never be reached\r\n    return 0.0;\r\n}\r\n\r\n\/**\r\n * Description:   Checks if the operation passed is supported and decodes it to\r\n *                enum value\r\n * \r\n * Parameters:    op - mathematical operation as a string, to be checked\r\n * \r\n * Return:        enum value representing the decoded mathematical operation\r\n *\/\r\nenum MathOperation GetOperation(const char *op)\r\n{\r\n    \/\/ Safety check for empty arg, support single character operations only  \r\n    if (op[0] == '\\0' || op[1] != '\\0')\r\n        ErrorHandler(ERR_OPERATION_INVALID);\r\n    \r\n    \/\/ Grab the character representing the operation\r\n    char opCode = op[0];\r\n    \r\n    switch (opCode)\r\n    {\r\n        case '+':\r\n            return OP_ADD;\r\n        case '-':\r\n            return OP_SUB;\r\n        case '\/':\r\n            return OP_DIV;\r\n        case '*':\r\n        case 'x':\r\n            return OP_MULT;\r\n        default:\r\n            return OP_UNKNOWN;\r\n    }\r\n}\r\n\r\n\/**\r\n * Description:   Checks if the operand is a decimal number, converts it to\r\n *                a double and returns it\r\n * \r\n * Parameters:    operand - operand being checked as string\r\n * \r\n * Return:        operand converted to double\r\n *\/\r\ndouble EvalOperand(const char *operand)\r\n{\r\n    \/\/ Used to keep track of the char currently being checked for validity\r\n    const char *p = operand;\r\n\r\n    \/\/ Skip first char if it's a sign\r\n    if (*p == '-' || *p == '+')\r\n        p++;\r\n    \r\n    int commaCount = 0;\r\n    while (*p)\r\n    {\r\n        if (*p == '.')\r\n        {\r\n            commaCount++;\r\n            if (commaCount &gt; 1)\r\n                ErrorHandler(ERR_OPERAND_MULT_SEPARATOR);\r\n        }\r\n        else if (!isdigit((unsigned char)*p))\r\n        {\r\n            ErrorHandler(ERR_OPERAND_UNKNOWN_SYMBOL);\r\n        }\r\n        \r\n        \/\/ Move to next character\r\n        p++;\r\n    }\r\n    \r\n    return atof(operand);\r\n}\r\n\r\n\/**\r\n * Description:   Prints error message, usage help and terminates the program\r\n * \r\n * Parameters:    code - error code that triggered exit condition\r\n * \r\n * Return:        -\r\n *\/\r\nvoid ErrorHandler(enum ErrorCode code)\r\n{\r\n    const char *errorPrintableText[] = \r\n    {\r\n        [ERR_ARG_CNT] = \"Invalid argument count\",\r\n        [ERR_UNRECOGNIZED_ARG] = \"Unrecognized argument\",\r\n        [ERR_OPERATION_INVALID] = \"Invalid operation\",\r\n        [ERR_OPERAND_MULT_SEPARATOR] = \"Invalid operand, unexpected decimal separator\",\r\n        [ERR_OPERAND_UNKNOWN_SYMBOL] = \"Invalid operand, not a number\",\r\n        [ERR_DIV_ZERO] = \"Dividing by zero\"\r\n    };\r\n    \r\n    fprintf(stderr, \"Error %d: \", code);\r\n    fprintf(stderr, \"%s\\n\", errorPrintableText[code]);\r\n\r\n    Usage();\r\n    exit(EXIT_FAILURE);\r\n}\r\n\r\n\/**\r\n * Description:   Prints program usage information\r\n * \r\n * Parameters:    -\r\n * \r\n * Return:        -\r\n *\/\r\nvoid Usage(void)\r\n{\r\n    printf(\"\\nUsage: %s operand operation operand\\n\\n\", execName);\r\n    printf(\"Possible operations: \\n\");\r\n    printf(\"\\t+ add\\n\");\r\n    printf(\"\\t- subtract\\n\");\r\n    printf(\"\\t* multiply\\n\");\r\n    printf(\"\\t\/ divide\\n\");\r\n    printf(\"\\nNote, that due to how shell works, \\n\"\r\n           \"the multiplication operator has to be encased in quotes\\n\"\r\n           \"e.g. 2 \\\"*\\\" 3.5\\n\");\r\n}\r\n\r\n\/**\r\n * Description:   Checks for the help argument, triggers usage help\r\n *                Checks if all arguments required for calculation are present\r\n * \r\n * Parameters:    argc - number of command line arguments\r\n *                argv - arguments that were passed\r\n * \r\n * Return:        -\r\n *\/\r\nvoid CheckArgs(int argc, char **argv)\r\n{\r\n    \/\/ Check for help argument\r\n    if (argc == 2)\r\n    {\r\n        if (!strcmp(argv[1], \"--help\"))\r\n        {\r\n            Usage();\r\n            exit(EXIT_SUCCESS);\r\n        }\r\n        ErrorHandler(ERR_UNRECOGNIZED_ARG);\r\n    }\r\n    \r\n    \/\/ Check expected arg count for calculator\r\n    if (argc != ARGS_CNT_EXPECTED)\r\n        ErrorHandler(ERR_ARG_CNT);\r\n}\r\n\r\n\/**\r\n * Description:   Prints out all command line arguments, for debugging purposes\r\n * \r\n * Parameters:    argc - number of command line arguments\r\n *                argv - arguments that were passed\r\n * \r\n * Return:        -\r\n *\/\r\nvoid DebugArgs(int argc, char **argv)\r\n{\r\n    printf(\"Total arguments: %d\\n\", argc);\r\n    for (int i = 0; i &lt; argc; i++)\r\n    {\r\n        printf(\"argv[%d] = %s\\n\", i, argv[i]);\r\n    }\r\n}<\/pre>\n<\/div>\n<div class=\"su-tabs-pane su-u-clearfix su-u-trim\" data-title=\"Struktuuridega lahendus\">\n<pre class=\"lang:c decode:true\">\/**\r\n * File:        calc_enum.c\r\n * Author:      Risto Heinsar\r\n * Created:     25.01.2026\r\n * Edited:      19.06.2026\r\n *\r\n * Description: Example program that's based on Programming 1 calculator lab.\r\n *              Introduces simple use cases for enum type.\r\n *\/\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;ctype.h&gt;\r\n#include &lt;string.h&gt;\r\n\r\n#define DEBUG 0\r\n\r\n#define ARGS_CNT_EXPECTED 4\r\n\r\nenum ArgsPosition { ARGS_EXEC, ARGS_OPERAND_1, ARGS_OPERATION, ARGS_OPERAND_2 };\r\nenum MathOperation { OP_ADD, OP_SUB, OP_MULT, OP_DIV, OP_UNKNOWN };\r\n\r\nenum ErrorCode\r\n{\r\n    ERR_ARG_CNT = 0,\r\n    ERR_UNRECOGNIZED_ARG,\r\n    ERR_OPERATION_INVALID,\r\n    ERR_OPERAND_MULT_SEPARATOR,\r\n    ERR_OPERAND_UNKNOWN_SYMBOL,\r\n    ERR_DIV_ZERO\r\n};\r\n\r\nstruct MathOperationEncoding\r\n{\r\n    char opCode;                        \/\/ opcodes as '+' etc\r\n    enum MathOperation operation;       \/\/ opcodes as OP_ADD etc\r\n};\r\n\r\nconst struct MathOperationEncoding mathOperations[] = {{'+', OP_ADD},\r\n                                                       {'-', OP_SUB},\r\n                                                       {'*', OP_MULT},\r\n                                                       {'x', OP_MULT},\r\n                                                       {'\/', OP_DIV }};\r\n\r\n\r\ndouble Calculate(double val1, double val2, enum MathOperation op);\r\nvoid ErrorHandler(enum ErrorCode code);\r\nvoid DebugArgs(int argc, char **argv);\r\ndouble EvalOperand(const char *operand);\r\nenum MathOperation GetOperation(const char *op);\r\nvoid Usage(void);\r\nvoid CheckArgs(int argc, char **argv);\r\n\r\n\/\/ Contains argv[0] to print exec path in Usage() for guidance \r\nconst char *execName;\r\n\r\nint main(int argc, char **argv)\r\n{\r\n    execName = argv[ARGS_EXEC];\r\n\r\n    CheckArgs(argc, argv);\r\n    \r\n    if (DEBUG) DebugArgs(argc, argv);\r\n\r\n    double val1 = EvalOperand(argv[ARGS_OPERAND_1]);\r\n    double val2 = EvalOperand(argv[ARGS_OPERAND_2]);\r\n\r\n    enum MathOperation op = GetOperation(argv[ARGS_OPERATION]);\r\n\r\n    printf(\"&gt; %.2f\\n\", Calculate(val1, val2, op));\r\n\r\n    return EXIT_SUCCESS;\r\n}\r\n\r\n\/**\r\n * Description:   Calculates the mathematical equation and returns the answer\r\n * \r\n * Parameters:    val1 - first operand\r\n *                val2 - second operand\r\n *                op - mathematical operation coded value\r\n * \r\n * Return:        result of the mathematical operation\r\n *\/\r\ndouble Calculate(double val1, double val2, enum MathOperation op)\r\n{\r\n    \/\/ Note: all cases either return or exit using ErrorHandler()\r\n    switch (op)\r\n    {\r\n        case OP_ADD:\r\n            return val1 + val2;\r\n        case OP_SUB:\r\n            return val1 - val2;\r\n        case OP_MULT:\r\n            return val1 * val2;\r\n        case OP_DIV:\r\n            if (val2 == 0)\r\n                ErrorHandler(ERR_DIV_ZERO);\r\n                \r\n            return val1 \/ val2;\r\n        default:\r\n            ErrorHandler(ERR_OPERATION_INVALID);\r\n    }\r\n    \r\n    \/\/ This should never be reached\r\n    return 0.0;\r\n}\r\n\r\n\/**\r\n * Description:   Checks if the operation passed is supported and decodes it to\r\n *                enum value\r\n * \r\n * Parameters:    op - mathematical operation as a string, to be checked\r\n * \r\n * Return:        enum value representing the decoded mathematical operation\r\n *\/\r\nenum MathOperation GetOperation(const char *op)\r\n{\r\n    \/\/ Safety check for empty arg, support single character operations only  \r\n    if (op[0] == '\\0' || op[1] != '\\0')\r\n        ErrorHandler(ERR_OPERATION_INVALID);\r\n    \r\n    \/\/ Grab the character representing the operation\r\n    char opCode = op[0];\r\n    \r\n    \/\/ Compare against the list of known operations\r\n    size_t opCount = sizeof(mathOperations) \/ sizeof(mathOperations[0]);\r\n    for (size_t i = 0; i &lt; opCount; i++)\r\n    {\r\n        if (opCode == mathOperations[i].opCode)\r\n            return mathOperations[i].operation;\r\n    }\r\n    \r\n    \/\/ No operation codes matched\r\n    return OP_UNKNOWN;\r\n}\r\n\r\n\/**\r\n * Description:   Checks if the operand is a decimal number, converts it to\r\n *                a double and returns it\r\n * \r\n * Parameters:    operand - operand being checked as string\r\n * \r\n * Return:        operand converted to double\r\n *\/\r\ndouble EvalOperand(const char *operand)\r\n{\r\n    \/\/ Used to keep track of the char currently being checked for validity\r\n    const char *p = operand;\r\n\r\n    \/\/ Skip first char if it's a sign\r\n    if (*p == '-' || *p == '+')\r\n        p++;\r\n    \r\n    int commaCount = 0;\r\n    while (*p)\r\n    {\r\n        if (*p == '.')\r\n        {\r\n            commaCount++;\r\n            if (commaCount &gt; 1)\r\n                ErrorHandler(ERR_OPERAND_MULT_SEPARATOR);\r\n        }\r\n        else if (!isdigit((unsigned char)*p))\r\n        {\r\n            ErrorHandler(ERR_OPERAND_UNKNOWN_SYMBOL);\r\n        }\r\n        \r\n        \/\/ Move to next character\r\n        p++;\r\n    }\r\n    \r\n    return atof(operand);\r\n}\r\n\r\n\/**\r\n * Description:   Prints error message, usage help and terminates the program\r\n * \r\n * Parameters:    code - error code that triggered exit condition\r\n * \r\n * Return:        -\r\n *\/\r\nvoid ErrorHandler(enum ErrorCode code)\r\n{\r\n    const char *errorPrintableText[] = \r\n    {\r\n        [ERR_ARG_CNT] = \"Invalid argument count\",\r\n        [ERR_UNRECOGNIZED_ARG] = \"Unrecognized argument\",\r\n        [ERR_OPERATION_INVALID] = \"Invalid operation\",\r\n        [ERR_OPERAND_MULT_SEPARATOR] = \"Invalid operand, unexpected decimal separator\",\r\n        [ERR_OPERAND_UNKNOWN_SYMBOL] = \"Invalid operand, not a number\",\r\n        [ERR_DIV_ZERO] = \"Dividing by zero\"\r\n    };\r\n    \r\n    fprintf(stderr, \"Error %d: \", code);\r\n    fprintf(stderr, \"%s\\n\", errorPrintableText[code]);\r\n\r\n    Usage();\r\n    exit(EXIT_FAILURE);\r\n}\r\n\r\n\/**\r\n * Description:   Prints program usage information\r\n * \r\n * Parameters:    -\r\n * \r\n * Return:        -\r\n *\/\r\nvoid Usage(void)\r\n{\r\n    printf(\"\\nUsage: %s operand operation operand\\n\\n\", execName);\r\n    printf(\"Possible operations: \\n\");\r\n    printf(\"\\t+ add\\n\");\r\n    printf(\"\\t- subtract\\n\");\r\n    printf(\"\\t* multiply\\n\");\r\n    printf(\"\\t\/ divide\\n\");\r\n    printf(\"\\nNote, that due to how shell works, \\n\"\r\n           \"the multiplication operator has to be encased in quotes\\n\"\r\n           \"e.g. 2 \\\"*\\\" 3.5\\n\");\r\n}\r\n\r\n\/**\r\n * Description:   Checks for the help argument, triggers usage help\r\n *                Checks if all arguments required for calculation are present\r\n * \r\n * Parameters:    argc - number of command line arguments\r\n *                argv - arguments that were passed\r\n * \r\n * Return:        -\r\n *\/\r\nvoid CheckArgs(int argc, char **argv)\r\n{\r\n    \/\/ Check for help argument\r\n    if (argc == 2)\r\n    {\r\n        if (!strcmp(argv[1], \"--help\"))\r\n        {\r\n            Usage();\r\n            exit(EXIT_SUCCESS);\r\n        }\r\n        ErrorHandler(ERR_UNRECOGNIZED_ARG);\r\n    }\r\n    \r\n    \/\/ Check expected arg count for calculator\r\n    if (argc != ARGS_CNT_EXPECTED)\r\n        ErrorHandler(ERR_ARG_CNT);\r\n}\r\n\r\n\/**\r\n * Description:   Prints out all command line arguments, for debugging purposes\r\n * \r\n * Parameters:    argc - number of command line arguments\r\n *                argv - arguments that were passed\r\n * \r\n * Return:        -\r\n *\/\r\nvoid DebugArgs(int argc, char **argv)\r\n{\r\n    printf(\"Total arguments: %d\\n\", argc);\r\n    for (int i = 0; i &lt; argc; i++)\r\n    {\r\n        printf(\"argv[%d] = %s\\n\", i, argv[i]);\r\n    }\r\n}\r\n<\/pre>\n<\/div>\n<div class=\"su-tabs-pane su-u-clearfix su-u-trim\" data-title=\"P\u00e4isefailiga lahendus\">\n<p>J\u00e4rgnev n\u00e4ide koosneb kahest koodifailist. M\u00f5lemad failid peavad paiknema samas kaustas. P\u00e4isefaili nimi l\u00e4htuvalt n\u00e4itest peab olema <span class=\"lang:c highlight:0 decode:true crayon-inline \">calc_enum.h<\/span> . See tuleneb koodifailis olevast <span class=\"lang:c highlight:0 decode:true crayon-inline \">#include<\/span>\u00a0 lausest. \u00dcldine tava on hoida koodi ja p\u00e4isefail samanimelised.<\/p>\n<p>P\u00e4isefaili t\u00f5steti koodifailist \u00fcmber:<\/p>\n<ul>\n<li>Kommentaarid, mis on suunatud funktsioonide kasutajale<\/li>\n<li>Makrod<\/li>\n<li>Struktuuride ja loendite deklaratsioonid<\/li>\n<li>Funktsioonide protot\u00fc\u00fcbid (deklaratsioonid)<\/li>\n<\/ul>\n<p>P\u00e4isefaili lisati t\u00e4iendavalt korduvdeklaratsiooni kaitse. Koodifaili lisati arendajale m\u00f5eldud l\u00fchikesed kommentaarid.<\/p>\n<pre class=\"lang:c decode:true\">\/**\r\n * File:        calc_struct_header.h\r\n * Author:      Risto Heinsar\r\n * Created:     25.01.2026\r\n * Edited:      05.03.2026\r\n *\r\n * Description: Example program that's based on Programming 1 calculator lab.\r\n *              Introduces simple use cases for enum type.\r\n *\/\r\n\r\n#ifndef CALC_STRUCT_HEADER_H\r\n#define CALC_STRUCT_HEADER_H\r\n\r\n#define DEBUG 0\r\n\r\n#define ARGS_CNT_EXPECTED 4\r\n\r\nenum ArgsPosition { ARGS_EXEC, ARGS_OPERAND_1, ARGS_OPERATION, ARGS_OPERAND_2 };\r\nenum MathOperation { OP_ADD, OP_SUB, OP_MULT, OP_DIV, OP_UNKNOWN };\r\n\r\nenum ErrorCode\r\n{\r\n    ERR_ARG_CNT = 0,\r\n    ERR_UNRECOGNIZED_ARG,\r\n    ERR_OPERATION_INVALID,\r\n    ERR_OPERAND_MULT_SEPARATOR,\r\n    ERR_OPERAND_UNKNOWN_SYMBOL,\r\n    ERR_DIV_ZERO\r\n};\r\n\r\nstruct MathOperationEncoding\r\n{\r\n    char opCode;                        \/\/ opcodes as '+' etc\r\n    enum MathOperation operation;       \/\/ opcodes as OP_ADD etc\r\n};\r\n\r\n\r\n\r\n\/**\r\n * Description:   Calculates the mathematical equation and returns the answer\r\n * \r\n * Parameters:    val1 - first operand\r\n *                val2 - second operand\r\n *                op - mathematical operation coded value\r\n * \r\n * Return:        result of the mathematical operation\r\n *\/\r\ndouble Calculate(double val1, double val2, enum MathOperation op);\r\n\r\n\r\n \/**\r\n * Description:   Checks if the operation passed is supported and decodes it to\r\n *                enum value\r\n * \r\n * Parameters:    op - mathematical operation as a string, to be checked\r\n * \r\n * Return:        enum value representing the decoded mathematical operation\r\n *\/\r\nenum MathOperation GetOperation(const char *op);\r\n\r\n\r\n \/**\r\n * Description:   Checks if the operand is a decimal number, converts it to\r\n *                a double and returns it\r\n * \r\n * Parameters:    operand - operand being checked as string\r\n * \r\n * Return:        operand converted to double\r\n *\/\r\ndouble EvalOperand(const char *operand);\r\n\r\n\r\n\/**\r\n * Description:   Prints error message, usage help and terminates the program\r\n * \r\n * Parameters:    code - error code that triggered exit condition\r\n * \r\n * Return:        -\r\n *\/\r\nvoid ErrorHandler(enum ErrorCode code);\r\n\r\n\r\n \/**\r\n * Description:   Prints program usage information\r\n * \r\n * Parameters:    -\r\n * \r\n * Return:        -\r\n *\/\r\nvoid Usage(void);\r\n\r\n\r\n\/**\r\n * Description:   Checks for the help argument, triggers usage help\r\n *                Checks if all arguments required for calculation are present\r\n * \r\n * Parameters:    argc - number of command line arguments\r\n *                argv - arguments that were passed\r\n * \r\n * Return:        -\r\n *\/\r\nvoid CheckArgs(int argc, char **argv);\r\n\r\n\r\n \/**\r\n * Description:   Prints out all command line arguments, for debugging purposes\r\n * \r\n * Parameters:    argc - number of command line arguments\r\n *                argv - arguments that were passed\r\n * \r\n * Return:        -\r\n *\/\r\nvoid DebugArgs(int argc, char **argv);\r\n\r\n#endif \/\/ CALC_STRUCT_HEADER_H\r\n<\/pre>\n<p>&nbsp;<\/p>\n<pre class=\"lang:c decode:true\">\/**\r\n * File:        calc_struct_header.c\r\n * Author:      Risto Heinsar\r\n * Created:     25.01.2026\r\n * Edited:      19.06.2026\r\n *\r\n * Description: Example program that's based on Programming 1 calculator lab.\r\n *              Introduces simple use cases for enum type.\r\n *\/\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;ctype.h&gt;\r\n#include &lt;string.h&gt;\r\n#include \"calc_struct_header.h.h\"\r\n\r\nconst struct MathOperationEncoding mathOperations[] = {{'+', OP_ADD},\r\n                                                       {'-', OP_SUB},\r\n                                                       {'*', OP_MULT},\r\n                                                       {'x', OP_MULT},\r\n                                                       {'\/', OP_DIV}};\r\n\r\n\r\n\/\/ Contains argv[0] to print exec path in Usage() for guidance \r\nconst char *execName;\r\n\r\nint main(int argc, char **argv)\r\n{\r\n    execName = argv[ARGS_EXEC];\r\n\r\n    CheckArgs(argc, argv);\r\n    \r\n    if (DEBUG) DebugArgs(argc, argv);\r\n\r\n    double val1 = EvalOperand(argv[ARGS_OPERAND_1]);\r\n    double val2 = EvalOperand(argv[ARGS_OPERAND_2]);\r\n\r\n    enum MathOperation op = GetOperation(argv[ARGS_OPERATION]);\r\n\r\n    printf(\"&gt; %.2f\\n\", Calculate(val1, val2, op));\r\n\r\n    return EXIT_SUCCESS;\r\n}\r\n\r\n\/**\r\n * Calculates the result, can cause exit on errors\r\n *\/\r\ndouble Calculate(double val1, double val2, enum MathOperation op)\r\n{\r\n    \/\/ Note: all cases either return or exit using ErrorHandler()\r\n    switch (op)\r\n    {\r\n        case OP_ADD:\r\n            return val1 + val2;\r\n        case OP_SUB:\r\n            return val1 - val2;\r\n        case OP_MULT:\r\n            return val1 * val2;\r\n        case OP_DIV:\r\n            if (val2 == 0)\r\n                ErrorHandler(ERR_DIV_ZERO);\r\n                \r\n            return val1 \/ val2;\r\n        default:\r\n            ErrorHandler(ERR_OPERATION_INVALID);\r\n    }\r\n    \r\n    \/\/ This should never be reached\r\n    return 0.0;\r\n}\r\n\r\n\/**\r\n * Checks the operation symbol, can throw errors that will exit\r\n *\/\r\nenum MathOperation GetOperation(const char *op)\r\n{\r\n    \/\/ Safety check for empty arg, support single character operations only  \r\n    if (op[0] == '\\0' || op[1] != '\\0')\r\n        ErrorHandler(ERR_OPERATION_INVALID);\r\n    \r\n    \/\/ Grab the character representing the operation\r\n    char opCode = op[0];\r\n    \r\n    \/\/ Compare against the list of known operations\r\n    size_t opCount = sizeof(mathOperations) \/ sizeof(mathOperations[0]);\r\n    for (size_t i = 0; i &lt; opCount; i++)\r\n    {\r\n        if (opCode == mathOperations[i].opCode)\r\n            return mathOperations[i].operation;\r\n    }\r\n    \r\n    \/\/ No operation codes matched\r\n    return OP_UNKNOWN;\r\n}\r\n\r\n\/**\r\n * Checks validity of the numeric string, can throw errors that will exit\r\n *\/\r\ndouble EvalOperand(const char *operand)\r\n{\r\n    \/\/ Used to keep track of the char currently being checked for validity\r\n    const char *p = operand;\r\n\r\n    \/\/ Skip first char if it's a sign\r\n    if (*p == '-' || *p == '+')\r\n        p++;\r\n    \r\n    int commaCount = 0;\r\n    while (*p)\r\n    {\r\n        if (*p == '.')\r\n        {\r\n            commaCount++;\r\n            if (commaCount &gt; 1)\r\n                ErrorHandler(ERR_OPERAND_MULT_SEPARATOR);\r\n        }\r\n        else if (!isdigit((unsigned char)*p))\r\n        {\r\n            ErrorHandler(ERR_OPERAND_UNKNOWN_SYMBOL);\r\n        }\r\n        \r\n        \/\/ Move to next character\r\n        p++;\r\n    }\r\n    \r\n    return atof(operand);\r\n}\r\n\r\n\/**\r\n * Prints error text and terminates the program\r\n *\/\r\nvoid ErrorHandler(enum ErrorCode code)\r\n{\r\n    const char *errorPrintableText[] = \r\n    {\r\n        [ERR_ARG_CNT] = \"Invalid argument count\",\r\n        [ERR_UNRECOGNIZED_ARG] = \"Unrecognized argument\",\r\n        [ERR_OPERATION_INVALID] = \"Invalid operation\",\r\n        [ERR_OPERAND_MULT_SEPARATOR] = \"Invalid operand, unexpected decimal separator\",\r\n        [ERR_OPERAND_UNKNOWN_SYMBOL] = \"Invalid operand, not a number\",\r\n        [ERR_DIV_ZERO] = \"Dividing by zero\"\r\n    };\r\n    \r\n    fprintf(stderr, \"Error %d: \", code);\r\n    fprintf(stderr, \"%s\\n\", errorPrintableText[code]);\r\n\r\n    Usage();\r\n    exit(EXIT_FAILURE);\r\n}\r\n\r\n\/**\r\n * Prints usage guide\r\n *\/\r\nvoid Usage(void)\r\n{\r\n    printf(\"\\nUsage: %s operand operation operand\\n\\n\", execName);\r\n    printf(\"Possible operations: \\n\");\r\n    printf(\"\\t+ add\\n\");\r\n    printf(\"\\t- subtract\\n\");\r\n    printf(\"\\t* multiply\\n\");\r\n    printf(\"\\t\/ divide\\n\");\r\n    printf(\"\\nNote, that due to how shell works, \\n\"\r\n           \"the multiplication operator has to be encased in quotes\\n\"\r\n           \"e.g. 2 \\\"*\\\" 3.5\\n\");\r\n}\r\n\r\n\r\n\/**\r\n * Checks command line arg count and --help, can throw errors to exit\r\n *\/\r\nvoid CheckArgs(int argc, char **argv)\r\n{\r\n    \/\/ Check for help argument\r\n    if (argc == 2)\r\n    {\r\n        if (!strcmp(argv[1], \"--help\"))\r\n        {\r\n            Usage();\r\n            exit(EXIT_SUCCESS);\r\n        }\r\n        ErrorHandler(ERR_UNRECOGNIZED_ARG);\r\n    }\r\n    \r\n    \/\/ Check expected arg count for calculator\r\n    if (argc != ARGS_CNT_EXPECTED)\r\n        ErrorHandler(ERR_ARG_CNT);\r\n}\r\n\r\n\/**\r\n * Prints list of passed command line arguments\r\n *\/\r\nvoid DebugArgs(int argc, char **argv)\r\n{\r\n    printf(\"Total arguments: %d\\n\", argc);\r\n    for (int i = 0; i &lt; argc; i++)\r\n    {\r\n        printf(\"argv[%d] = %s\\n\", i, argv[i]);\r\n    }\r\n}\r\n<\/pre>\n<\/div><\/div><\/div>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>J\u00e4rgneva n\u00e4ite eesm\u00e4rk on tutvustada loendite (enum ) deklareerimist ning kasutamist programmiga, mis on juba Programmeerimine 1 raames tuttav. N\u00e4ites on loodud kolm loendit K\u00e4sureaargumentide kirjeldamiseks Veakoodide kodeerimiseks Matemaatiliste operatsioonide kodeerimiseks N\u00e4itest on loodud kolm varianti, mis k\u00f5ik vastavad erinevatele teadmiste astmele erinevatel hetkedel kursusel Baaslahendus on sobilik n\u00e4dalal 2. See rakendab vaid loendeid. Struktuuridega &hellip; <a href=\"https:\/\/blue.pri.ee\/ttu\/programmeerimine-ii\/koodinaited\/loendite-naide-kasurea-kalkulaatori-pohjal\/\" class=\"more-link\">Loe edasi <span class=\"screen-reader-text\">Loendite ja p\u00e4isefaili n\u00e4ide k\u00e4surea kalkulaatori p\u00f5hjal<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":684,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"page-templates\/code-width-wide.php","meta":{"footnotes":""},"class_list":["post-11128","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/pages\/11128","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/comments?post=11128"}],"version-history":[{"count":18,"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/pages\/11128\/revisions"}],"predecessor-version":[{"id":11507,"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/pages\/11128\/revisions\/11507"}],"up":[{"embeddable":true,"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/pages\/684"}],"wp:attachment":[{"href":"https:\/\/blue.pri.ee\/ttu\/wp-json\/wp\/v2\/media?parent=11128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}