2020-04-02 21:26:14 +00:00
|
|
|
#include<stdio.h>
|
|
|
|
#include<stdlib.h>
|
|
|
|
#include<string.h>
|
|
|
|
#include<stdbool.h>
|
|
|
|
#include<ctype.h>
|
|
|
|
|
|
|
|
#define SCAN_FIRST_NUMBER 0
|
|
|
|
#define SCAN_FIRST_OPERATOR 1
|
|
|
|
#define SCAN_SECOND_NUMBER 2
|
|
|
|
#define SCAN_SECOND_OPERATOR 3
|
|
|
|
#define SCAN_RESULT 4
|
|
|
|
|
|
|
|
char* scanValue(char *s, float *output);
|
|
|
|
char* scanOperator(char *s, char *output);
|
|
|
|
|
|
|
|
bool isOperator(char c);
|
|
|
|
bool isNewline(char c);
|
|
|
|
bool evaluate(float a, float b, float c, char op);
|
|
|
|
|
|
|
|
void error();
|
|
|
|
|
|
|
|
int main(){
|
|
|
|
char buffer[2048];
|
2020-04-02 21:34:39 +00:00
|
|
|
char *retVal;
|
2020-04-02 21:26:14 +00:00
|
|
|
|
2020-04-02 21:34:39 +00:00
|
|
|
while ((retVal = fgets(buffer, sizeof(buffer), stdin)) != 0) {
|
|
|
|
float a;
|
|
|
|
float b;
|
|
|
|
float c;
|
|
|
|
char operator;
|
2020-04-02 21:26:14 +00:00
|
|
|
|
2020-04-02 21:34:39 +00:00
|
|
|
if (retVal == 0 || isNewline(buffer[0]) == true) {
|
|
|
|
// puts("KONIEC");
|
2020-04-02 21:26:14 +00:00
|
|
|
|
2020-04-02 21:34:39 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2020-04-02 21:26:14 +00:00
|
|
|
|
2020-04-02 21:34:39 +00:00
|
|
|
int l = strlen(buffer);
|
2020-04-02 21:26:14 +00:00
|
|
|
|
2020-04-02 21:34:39 +00:00
|
|
|
if (isNewline(buffer[l - 1]) == false) {
|
|
|
|
error();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2020-04-02 21:26:14 +00:00
|
|
|
|
2020-04-02 21:34:39 +00:00
|
|
|
int scanStatus = SCAN_FIRST_NUMBER;
|
|
|
|
char *currentChar = buffer;
|
|
|
|
char *endChar = buffer + l - 1;
|
|
|
|
|
|
|
|
while (currentChar < endChar) {
|
|
|
|
if (scanStatus == SCAN_FIRST_NUMBER) {
|
|
|
|
retVal = scanValue(currentChar, &a);
|
|
|
|
} else if (scanStatus == SCAN_FIRST_OPERATOR) {
|
|
|
|
retVal = scanOperator(currentChar, &operator);
|
|
|
|
} else if (scanStatus == SCAN_SECOND_NUMBER) {
|
|
|
|
retVal = scanValue(currentChar, &b);
|
|
|
|
} else if (scanStatus == SCAN_SECOND_OPERATOR) {
|
|
|
|
char eqOp;
|
|
|
|
|
|
|
|
retVal = scanOperator(currentChar, &eqOp);
|
|
|
|
|
|
|
|
if (eqOp != '=') {
|
|
|
|
retVal = 0;
|
|
|
|
}
|
|
|
|
} else if (scanStatus == SCAN_RESULT) {
|
|
|
|
retVal = scanValue(currentChar, &c);
|
2020-04-02 21:47:27 +00:00
|
|
|
|
|
|
|
if (endChar - retVal > sizeof(char)) {
|
|
|
|
error();
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2020-04-02 21:34:39 +00:00
|
|
|
} else {
|
|
|
|
error();
|
2020-04-02 21:26:14 +00:00
|
|
|
|
2020-04-02 21:34:39 +00:00
|
|
|
break;
|
2020-04-02 21:26:14 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 21:34:39 +00:00
|
|
|
if (retVal == 0) {
|
|
|
|
error();
|
2020-04-02 21:26:14 +00:00
|
|
|
|
2020-04-02 21:34:39 +00:00
|
|
|
break;
|
|
|
|
} else if (scanStatus == SCAN_RESULT) {
|
2020-04-02 21:47:27 +00:00
|
|
|
if (operator == '/' && b == 0) {
|
|
|
|
error();
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-04-02 21:34:39 +00:00
|
|
|
bool validResult = evaluate(a, b, c, operator);
|
2020-04-02 21:26:14 +00:00
|
|
|
|
2020-04-02 21:34:39 +00:00
|
|
|
if (validResult == true) {
|
|
|
|
puts("OK");
|
|
|
|
} else {
|
|
|
|
puts("ZLE");
|
|
|
|
}
|
2020-04-02 21:26:14 +00:00
|
|
|
|
2020-04-02 21:34:39 +00:00
|
|
|
break;
|
2020-04-02 21:26:14 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 21:34:39 +00:00
|
|
|
currentChar = retVal;
|
|
|
|
scanStatus++;
|
2020-04-02 21:26:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* scanValue(char *s, float *output) {
|
|
|
|
char *retVal = 0;
|
|
|
|
|
|
|
|
*output = strtof(s, &retVal);
|
|
|
|
|
|
|
|
if (retVal == 0 || retVal == s || ((*output) == 0 && *(retVal - 1) != '0')) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* scanOperator(char *s, char *output) {
|
|
|
|
char *start = s;
|
|
|
|
|
|
|
|
while (isspace(*start) != 0) {
|
|
|
|
start++;
|
|
|
|
}
|
|
|
|
|
|
|
|
char c = *start;
|
|
|
|
|
|
|
|
if (isOperator(c) == false) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
(*output) = c;
|
|
|
|
|
|
|
|
return start + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isOperator(char c) {
|
|
|
|
return c == '+' || c == '-' || c == '*' || c == '/' || c == '=';
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isNewline(char c) {
|
|
|
|
return c == '\n';
|
|
|
|
}
|
|
|
|
|
|
|
|
bool evaluate(float a, float b, float c, char op) {
|
|
|
|
float resultL = c - 0.001F;
|
|
|
|
float resultR = c + 0.001F;
|
|
|
|
float result;
|
|
|
|
|
|
|
|
switch (op)
|
|
|
|
{
|
|
|
|
case '+':
|
|
|
|
result = a + b;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '-':
|
|
|
|
result = a - b;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '*':
|
|
|
|
result = a * b;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '/':
|
|
|
|
result = a / b;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
error();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result == c || (result >= resultL && result <= resultR);
|
|
|
|
}
|
|
|
|
|
|
|
|
void error() {
|
|
|
|
puts("CHYBA");
|
|
|
|
}
|