Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * calc.c : Simple command line calculator.
- * calc executes simple operations read from an input string.
- * The string can be supplied either as the first command line argument or by
- * calling "calc_parse" manually.
- *
- * EBNF for math:
- * <expression> ::= ( <expression> <operator> <expression> ) |
- * ( <number> <operator> <number> )
- * <operator> ::= "+" | "-" | "/" | "*"
- *
- */
- #include <stdio.h>
- #include <string.h>
- // The macro _WIN32 must be defined when compiling for windows (gcc -D _WIN32 1).
- #ifdef _WIN32
- #define SEP '\\'
- #else
- #define SEP '/'
- #endif
- typedef enum { CALC_OK, CALC_ESYNTAX, CALC_EOPER } CalcError_t;
- void calc_strerror( CalcError_t errno ) {
- switch (errno) {
- case CALC_ESYNTAX:
- return (void) fputs("CALC: Syntax Error", stderr);
- case CALC_EOPER:
- return (void) fputs("CALC: Invalid Operator", stderr);
- }
- }
- CalcError_t calc_parse(char *string, double *result) {
- int count, pos = -1;
- double res, a;
- char op;
- CalcError_t error = CALC_OK;
- count = sscanf(string, " %lf %c %lf%n", &res, &op, &a, &pos);
- if (count == EOF) return CALC_OK;
- if (count != 3) return CALC_ESYNTAX;
- do {
- switch (op) {
- case '+':
- res += a; break;
- case '-':
- res -= a; break;
- case '*':
- res *= a; break;
- case '/':
- res /= a; break;
- default:
- return CALC_EOPER;
- }
- string += pos;
- count = sscanf(string, " %c %lf%n", &op, &a, &pos);
- } while (count == 2);
- if (count != EOF) return CALC_ESYNTAX;
- *result = res;
- return CALC_OK;
- }
- int main(int argc, char *argv[]) {
- if (argc == 1) {
- char *name = strrchr(argv[0], SEP);
- name = name != NULL ? ++name : argv[0];
- fprintf(stderr, "Usage: %s expressions...\n"
- "Example: %s \"12.2 * 73 - 4.5\"\n", name, name);
- return 1;
- }
- double res = 0;
- CalcError_t error;
- error = calc_parse(argv[1], &res);
- if (error != CALC_OK) {
- calc_strerror( error );
- return 1;
- }
- printf("Result: %g", res);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment