создать числовое выражение в c, используя переменные char и int - PullRequest
0 голосов
/ 24 апреля 2018

Здравствуйте, я хочу сделать что-то вроде этого:

int a=1,b=2,c=3,w=4,result;
char d='+',e='-',f='/',g='*';

a d b g w  =result;
printf("%d",result);

где результат должен быть 1 + 2 * 4 в этом примере какие-нибудь идеи, как я могу это сделать?

Ответы [ 3 ]

0 голосов
/ 24 апреля 2018

Это частичная подсказка для вас.

Что это может сделать: a + b;а - б;а * б;a / b;

Примечание

a / b не даст правильных ответов, потому что делает целочисленное деление.

Что не может сделать

Правильная математика, сделай кофе и все остальное

silly_calc.c

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>

enum operation {
    INVALID,
    CONTINUE, /* got just a number */
    QUIT,
    PLUS,
    MINUS,
    MULTIPLY,
    DIVIDE
};

enum operation parse(char *expr, int *left, int *right);
int eval(const char *expr);

char *remove_spaces(char *expr);

int main() {
    char expr[256];
    FILE *fp = stdin;
    char *rv;
    int left, right;
    enum operation oper = CONTINUE;

    while (oper != QUIT) {
        fputc(':', stdout);
        rv = fgets(expr, sizeof(expr), fp);
        if( rv == NULL ) {
            if(feof(fp)) {
                fprintf(stderr, "someone closed the input\n");
                break;
            }
            if(ferror(fp)) {
                fprintf(stderr, "something bad happened\n");
                break;
            }
        }
        oper = parse(expr, &left, & right);
        /* this switch should be moved into an eval function 
         * which would deal with precedence of operations etc.
         */
        switch(oper) {
            case CONTINUE:
                fprintf (stderr, "%d\n", left);
                continue;
            case INVALID:
                fprintf(stderr, "> Don't know what to do with %-32s...\n", expr);
                continue;
            case QUIT:
                fprintf(stderr, "> quitting\n");
                break;

            case PLUS:
                fprintf(stdout, "%d\n", left + right);
                break;
            case MINUS:
                fprintf(stdout, "%d\n", left - right);
                break;
            case MULTIPLY:
                fprintf(stdout, "%d\n", left * right);
                break;
            case DIVIDE:
                fprintf(stdout, "%d\n", left / right);
                break;
        }
    }

    return 0;
}

enum operation next_expr(char *expr, int *left, int *right) 
{
    enum operation oper;
    char *nextbit = NULL;
    *left = strtol(expr, &nextbit, 10);
    if ((*left == 0 && errno == EINVAL) || nextbit == expr ) {
        if(strcasecmp(expr, "quit") == 0)
            return QUIT;
        return INVALID;
    }
    if (*nextbit == 0 )
        return CONTINUE;

    switch(*nextbit) {
        case '+': oper = PLUS; break;
        case '-': oper = MINUS; break;
        case '*': oper = MULTIPLY; break;
        case '/': oper = DIVIDE; break;
        default: 
            return INVALID;
    }
    expr = nextbit+1; /* move over to the next number */
    *right = strtol(expr, &nextbit, 10);
    if((*right == 0 && errno == EINVAL ) || nextbit == expr) {
        return INVALID;
    }
    /* what if there are still more bits in next bit? */
    return oper;
}

enum operation parse(char *expr, int *left, int *right)
{
    enum operation suboperation;
    remove_spaces(expr);
    suboperation = next_expr(expr, left, right);
    /* TODO: take care of the rest of the bits that are in the expr */
    return suboperation;
}

char * remove_spaces(char *expr)
{
    char *p = expr, *q = expr;
    while(*q != 0) {
        *p = *q; 
        q++;
        if(!isspace(*p))
            p++;
    }
    *p = 0;
    return expr;
}
0 голосов
/ 25 апреля 2018

Вы не можете выполнять динамическую арифметику в Си так, как пытаетесь.С препроцессором можно выполнять ограниченные трюки для выражений с постоянными времени компиляции, но для общего решения вам нужен оценщик выражений.

Вот упрощенный оценщик, который поддерживает 4 базовых оператора с проверками ограниченной работоспособности:

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

long long eval(const char *s) {
    struct operand {
        long long val;
        int op, prec;
    } stack[16], *sp, x;

    for (sp = stack;;) {
        x.val = strtoll(s, (char **)&s, 0);
        while (isspace((unsigned char)*s))
            s++;

        switch (x.op = *s++) {
        case '*':
        case '/':
        case '%': x.prec = 2; break;
        case '+':
        case '-': x.prec = 1; break;
        default:  x.prec = 0; x.op = 0; break;
        }

        while (sp > stack && x.prec <= sp[-1].prec) {
            switch ((--sp)->op) {
            case '*': x.val = sp->val * x.val; break;
            case '/': x.val = sp->val / x.val; break;
            case '%': x.val = sp->val % x.val; break;
            case '+': x.val = sp->val + x.val; break;
            case '-': x.val = sp->val - x.val; break;
            }
        }
        if (!x.op)
            return x.val;

        if (sp == stack + sizeof(stack) / sizeof(stack[0])) {
            errno = ERANGE;     /* expression complexity error */
            return 0;
        }
        *sp++ = x;
    }
}

int main(int argc, char *argv[]) {
    if (argc > 1) {
        for (int i = 1; i < argc; i++) {
            printf("%s -> %lld\n", argv[i], eval(argv[i]));
        }
    } else {
        char buf[80];
        int a = 1, b = 2, c = 3, w = 4, result;

        for (int i = 0; i < 4*4*4; i++) {
            snprintf(buf, sizeof buf, "%d %c %d %c %d %c %d",
                     a, "+-/*"[i / 16],
                     b, "+-/*"[i / 4 % 4],
                     c, "+-/*"[i % 4],
                     w);
            result = eval(buf);
            printf("%s -> %d\n", buf, result);
        }
    }
    return 0;
}

Вывод:

1 + 2 + 3 + 4 -> 10
1 + 2 + 3 - 4 -> 2
1 + 2 + 3 / 4 -> 3
1 + 2 + 3 * 4 -> 15
1 + 2 - 3 + 4 -> 4
1 + 2 - 3 - 4 -> -4
1 + 2 - 3 / 4 -> 3
1 + 2 - 3 * 4 -> -9
1 + 2 / 3 + 4 -> 5
1 + 2 / 3 - 4 -> -3
1 + 2 / 3 / 4 -> 1
1 + 2 / 3 * 4 -> 1
1 + 2 * 3 + 4 -> 11
1 + 2 * 3 - 4 -> 3
1 + 2 * 3 / 4 -> 2
1 + 2 * 3 * 4 -> 25
1 - 2 + 3 + 4 -> 6
1 - 2 + 3 - 4 -> -2
1 - 2 + 3 / 4 -> -1
1 - 2 + 3 * 4 -> 11
1 - 2 - 3 + 4 -> 0
1 - 2 - 3 - 4 -> -8
1 - 2 - 3 / 4 -> -1
1 - 2 - 3 * 4 -> -13
1 - 2 / 3 + 4 -> 5
1 - 2 / 3 - 4 -> -3
1 - 2 / 3 / 4 -> 1
1 - 2 / 3 * 4 -> 1
1 - 2 * 3 + 4 -> -1
1 - 2 * 3 - 4 -> -9
1 - 2 * 3 / 4 -> 0
1 - 2 * 3 * 4 -> -23
1 / 2 + 3 + 4 -> 7
1 / 2 + 3 - 4 -> -1
1 / 2 + 3 / 4 -> 0
1 / 2 + 3 * 4 -> 12
1 / 2 - 3 + 4 -> 1
1 / 2 - 3 - 4 -> -7
1 / 2 - 3 / 4 -> 0
1 / 2 - 3 * 4 -> -12
1 / 2 / 3 + 4 -> 4
1 / 2 / 3 - 4 -> -4
1 / 2 / 3 / 4 -> 0
1 / 2 / 3 * 4 -> 0
1 / 2 * 3 + 4 -> 4
1 / 2 * 3 - 4 -> -4
1 / 2 * 3 / 4 -> 0
1 / 2 * 3 * 4 -> 0
1 * 2 + 3 + 4 -> 9
1 * 2 + 3 - 4 -> 1
1 * 2 + 3 / 4 -> 2
1 * 2 + 3 * 4 -> 14
1 * 2 - 3 + 4 -> 3
1 * 2 - 3 - 4 -> -5
1 * 2 - 3 / 4 -> 2
1 * 2 - 3 * 4 -> -10
1 * 2 / 3 + 4 -> 4
1 * 2 / 3 - 4 -> -4
1 * 2 / 3 / 4 -> 0
1 * 2 / 3 * 4 -> 0
1 * 2 * 3 + 4 -> 10
1 * 2 * 3 - 4 -> 2
1 * 2 * 3 / 4 -> 1
1 * 2 * 3 * 4 -> 24

При таком подходе вычисление всех возможных комбинаций операторов, включая группирование в скобках и переупорядочение, более сложное.

0 голосов
/ 24 апреля 2018

Если вы хотите напечатать результат в виде строки, то вам нужно следующее:

int a=1,b=2,c=3,w=4,result;
char d='+',e='-',f='/',g='*';

//a d b g w  =result;
printf("%d %c %d %c %d", a, d, b, g, w);

Но, если вы хотите вычислить результат выражения, вам нужно будет создать функцию длясделай это.Что-то вроде это .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...