pvjc20/du4/program.c
2020-04-02 23:34:39 +02:00

169 lines
3.5 KiB
C

#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];
char *retVal;
while ((retVal = fgets(buffer, sizeof(buffer), stdin)) != 0) {
float a;
float b;
float c;
char operator;
if (retVal == 0 || isNewline(buffer[0]) == true) {
// puts("KONIEC");
return 0;
}
int l = strlen(buffer);
if (isNewline(buffer[l - 1]) == false) {
error();
return 0;
}
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);
} else {
error();
break;
}
if (retVal == 0) {
error();
break;
} else if (scanStatus == SCAN_RESULT) {
bool validResult = evaluate(a, b, c, operator);
if (validResult == true) {
puts("OK");
} else {
puts("ZLE");
}
break;
}
currentChar = retVal;
scanStatus++;
}
}
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");
}