#include #include #include #include #include #include #define SIZE 128 #define TEMPBUFFERSIZE 32 //kontrola, ze ci vycitane informacie su aritmeticky spravne //VRACIA: int: -1 (CHYBA), 0 (False), 1 (True) float IsArithCorrect(float num1, float num2, char op, float result) { float calcResult = 0; if (op == '/' && num2 == 0) { return 0;} switch (op) { case '-': calcResult = num1 - num2; break; case '+': calcResult = num1 + num2; break; case '*': calcResult = num1 * num2; break; case '/': calcResult = num1 / num2; break; } calcResult = roundf(calcResult* 100.0f) / 100.0f; result = roundf(result * 100.0f) / 100.0f; if (calcResult == result) { return 1; } return 0; } int main() { //pomocne premeny char line[SIZE], strBuffer[SIZE]; line[0] = '\0'; char* strtofEndPtr; int LinesOnInputCount = 0; while (fgets(line, SIZE, stdin) != NULL) { //predbezne handlovanie neplatnych zaznamov if (line[0] == '\n' || line[0] == '\0') { break; } //reset pamate, tak aby po kazdom riadku sa nahodou nenacital vstup z predosleho... strBuffer[0] = '\0'; sscanf(line, "%127[^\n]", strBuffer); if (strBuffer[0] == '\0') { printf("CHYBA\n"); continue; } bool isLineInvalid = false; //docasne 'char' premeny char num1Temp[TEMPBUFFERSIZE], num2Temp[TEMPBUFFERSIZE], resultTemp[TEMPBUFFERSIZE]; num1Temp[0] = '\0'; num2Temp[0] = '\0'; resultTemp[0] = '\0'; bool foundEqualSign = false; char op1 = 'N'; //N = 'None/NIC' for (int i = 0; strBuffer[i] != '\0'; i++) { bool isNegativeSign = false; if (isspace(strBuffer[i]) != 0) { continue; } if (strBuffer[i] == '-') { //kontrola - zistenie, ze ci znak '-' symbolizuje zapornu hodnotu (-456) alebo arit. operaciu minus //zistujeme to na zaklade toho, kde sme v riadku (ak sme na zaciatku num1, num2 alebo vyslednehoCisla, tak sa jedna o minusove znamienko) if (op1 == 'N' && strlen(num1Temp) == 0) { isNegativeSign = true; } else if (op1 != 'N' && !foundEqualSign && strlen(num2Temp) == 0) { isNegativeSign = true; } else if (foundEqualSign && strlen(resultTemp) == 0) { isNegativeSign = true; } } if (isdigit(strBuffer[i]) != 0 || strBuffer[i] == '.' || isNegativeSign) { //cislo sa bude zapisovat podla toho, kde sme pri citani riadku... //ak nenasiel ani arit. znamienko = cislo patri ku prvemu operandu (num1) //ak nasiel arit. znamienko ale NIE este symbol '=', tak cislo patri ku druhemu operandu (num2) //inak ak ma vsetko, tak zvysne nacitane cisla z riadku mozu byt vyluc. metodou len sucastou vysledku if (op1 == 'N') { strncat(num1Temp, &strBuffer[i], 1); } else if (!foundEqualSign) { strncat(num2Temp, &strBuffer[i], 1); } else { strncat(resultTemp, &strBuffer[i], 1); } } else if (strBuffer[i] == '=') { foundEqualSign = true; continue; } else if (strBuffer[i] == '+' || strBuffer[i] == '-' || strBuffer[i] == '/' || strBuffer[i] == '*') { //predbezna kontrola, ak uz operator mame tak vyhod chybu pri druhom pokuse o nacitanie //taktiez, ak sa nasiel minusovy znak tu tak to moze byt len arit. znamienko if (op1 != 'N') { isLineInvalid = true; } op1 = strBuffer[i]; } else { isLineInvalid = true; break; } } float num1 = strtof(num1Temp, &strtofEndPtr); float num2 = strtof(num2Temp, &strtofEndPtr); float resultNum = strtof(resultTemp, &strtofEndPtr); //** konecna faza = vypisovanie vysledkov //ak systematicka chyba if (isLineInvalid || op1 == 'N' || IsArithCorrect(num1, num2, op1, resultNum) == -1) { printf("CHYBA\n"); } else if (IsArithCorrect(num1, num2, op1, resultNum) == 0) { printf("ZLE\n"); } else { printf("OK\n"); } } return 0; }