C语言学习11-1:字符计算器

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void eat_space(char *s)
{
    int i = 0, j = 0;
    while ((s[i] = s[j++]) != '')
        if (s[i] != ' ')
            i++;
}

double expr(char *);

char *extract(char *s, int *index)
{
    int cnt = 0;
    int start_pos = *index, len;
    char *sub_expr = NULL;

    while (s[*index] != '')
    {
        switch (s[*index])
        {
            case '(':
                cnt++;
                break;
            case ')':
                cnt--;    
                if (cnt == 0)
                {
                    len = *index - start_pos - 1;    
                    printf("start = %d, *index = %d, len = %d
", 
                        start_pos, *index, len);
                    sub_expr = malloc(len + 1);
                    if (NULL == sub_expr)
                    {
                        printf("内存不足!
");    
                        exit(1);
                    }
                    memcpy(sub_expr, s + start_pos + 1, len);
                    sub_expr[len] = '';
                    return sub_expr;
                }
                break;
        }
        *index += 1;
    }

    printf("括号不匹配, 跑出整个表达式, 表达式错误!
");
    exit(1);
}

double number(char *s, int *index)
{
    double val = 0.0;
    char *subexpr = NULL;

    if (s[*index] == '(')
    {
        subexpr = extract(s, index);    
        val = expr(subexpr);
        printf("subexpr = %s, val = %lf
", subexpr, val);
        free(subexpr);

        *index += 1;
        return val;
    }

    if (!strchr("0123456789", s[*index]))
        goto err0;

    while ('0' <= s[*index] && s[*index] <= '9')
    {
        val *= 10;    
        val += s[*index] - '0';
        *index += 1;
    }

    if (s[*index] != '.')
        return val;

    if (!strchr("0123456789", s[(*index) + 1]))
        goto err0;

    double factor = 1.0;
    while ('0' <= s[++*index] && s[*index] <= '9')
    {
        factor *= 0.1;
        val += factor * (s[*index] - '0');
    }

    return val;

err0:
    printf("表达式中包含不合法字符!
");
    exit(1);
}

double term(char *s, int *index)
{
    double ret = 0.0;

    ret = number(s, index);

    while (s[*index] == '*' || s[*index] == '/')
    {
        if (s[*index] == '*')    
        {
            *index += 1;
            ret *= number(s, index);    
        }
        if (s[*index] == '/')
        {
            *index += 1;    
            ret /= number(s, index);
        }
    }

    return ret;
}

double expr(char *s)
{
    double ret = 0.0;
    int index = 0;

    ret = term(s, &index);
    while (1)
    {
        switch (s[index++])    
        {
            case '+':
                ret += term(s, &index);
                break;
            case '-':
                ret -= term(s, &index);
                break;
            case '':
                return ret;
                break;
            default:
                goto err0;
                break;
        }
    }

err0:
    printf("错误的表达式.
");
    exit(1);
}

int main(void)
{
    char s[1024];

    printf("pls input a expression: ");
    gets(s);
    eat_space(s);
    puts(s);

    printf("------------
");

    printf("the result of this expression is: %lf
", expr(s));

    return 0;
}
原文地址:https://www.cnblogs.com/will-boot/p/3355199.html