在缓冲区中解决表达式

时间:2011-07-05 19:37:32

标签: c parsing

我正在尝试创建一个函数(在C中)来解决放在缓冲区变量中的加法。到目前为止它适用于导致一位数字的方程式,但是如果结果超过一位数,则会导致问题。例如,如果我在缓冲区中放置2 + 3 + 5 + 2,则输出102,而不是12.任何人都可以指出我的错误在哪里以及如何解决它们吗?

这是我的代码:

char buffer[50];

void *adder(void)
{
    int bufferlen;
    int value1, value2;
    int startOffset, remainderOffset;
    int i;
    char result[10];
    while (1) 
    {
        startOffset = remainderOffset = -1;
        value1 = value2 = -1;

        bufferlen = strlen(buffer);
        for (i = 0; i < bufferlen; i++) {
            if(value1 == -1)
            {
                if(isNumeric(buffer[i]))
                {
                    value1 = string2int(&buffer[i]);
                    startOffset = i;
                }
            }
            else
            {
                if(buffer[i] == 43)
                {
                    if(isNumeric(buffer[i+1]))
                    {
                        value2 = string2int(&buffer[i+1]);
                        remainderOffset = i+1;
                    }
                }
            }

            if(value1 != -1 && value2 != -1)
            {
                int k=0;
                int j=0;
                int2string((value1 + value2),result);
                /* print out the number we've found */
                fprintf(stdout, "Re:%s\n", result);
                int resultlen = strlen(result);
                for(k=startOffset; k < bufferlen; k++)
                {
                    if(j < resultlen)
                    {
                        buffer[k] = result[j];
                        j++;
                    }
                    else
                    {
                        /* shift the remainder of the string to the left */
                        printf("A1-Buffer:%s\nk=%i\n", buffer, k);
                        if(j > 0)
                        buffer[k] = buffer[k+2];
                        else
                        buffer[k] = buffer[k+2];
                        printf("A2-Buffer:%s\n", buffer);
                        i = i - remainderOffset;
                        startOffset = remainderOffset = -1;
                        value1 = value2 = -1;   
                    }
                }
            }
        }
    break;
    }

}

编辑:啊,对不起,忘记了额外的功能。此函数用于学校作业,isNumeric()和String2int()与isdigit()和atoi()完全相同,并提供给我们在函数中使用。

编辑2:添加数字后,必须将结果添加回表达式中的缓冲区,如下所示:(2 + 3) - &gt; (5)原因是最终将编写更多的函数来处理乘法,除法等。这是我的主要挫折所在 - 将结果放在表达式的位置并将缓冲区移到适当的位置。

2 个答案:

答案 0 :(得分:1)

char buffer[50];

为什么50个字节?为什么不100?您应该接受指针作为参数,而不是依赖于全局。此外,buffer不是描述性名称。

void *adder(void)

该函数不返回void *;它没有回报价值。你可以考虑

/* return value of expression */
int evaluate_add_expression( char const *in_string )

/* return status code */
int evaluate_add_expression( char const *in_string, int *out_value ) 

接下来,在不初始化变量的情况下声明许多变量。将声明移动到循环中并包含声明的初始化,即int value1 = -1, value2 = -1;当然,这些名称根本不具有描述性。

            if(buffer[i] == 43)

'+'是表示加号字符的更好方式,而不是幻数43。


如果我是你,我会利用sscanf功能。

int evaluate_add_expression( char const *in_string, int *sum ) {
    int addend;
    size_t offset, offset_delta;

    if ( sscanf( in_string, " %d %zn", sum, &offset ) != 1 ) return 1;

    while ( sscanf( in_string + offset, "+ %d %zn", &addend, &offset_delta ) == 1 ) {
        * sum += addend;
        offset += offset_delta;
    }

    return in_string[ offset ] != '\0'; /* check that all input was consumed */
}

这个工作正常,大约15%。

答案 1 :(得分:1)

请注意

 if(j > 0)
     buffer[k] = buffer[k+2];
 else
     buffer[k] = buffer[k+2];
无论j的值如何,

都会执行相同的代码。另请注意,j在您的代码中永远不会为负数。

你的缓冲阵列越界越界。您的循环计数器i在每个循环结束时递增1,但您也在执行

i = i - remainderOffset;
k循环中

多次。当然,必须给你一个负面的i

此外,当您使用

移回缓冲区时
 buffer[k] = buffer[k+2];

循环将k提升到bufferLen,因此此处k+2也超出范围。

我不确定为什么要把所有东西都移回固定数量的两个位置呢?当然,假设您刚刚添加了一位数字?

考虑这些问题,你会开始看到你哪里出错了。我同意其他人的意见,如果你可以利用现有的代码,那么就这样做。

编辑:回复您的评论

我认为它是将结果存储在缓冲区中的赋值的一部分?如果没有,那么只需在整数中跟踪它,一切都简化了。如果赋值说您必须使用中间结果更新缓冲区,请注意以下内容:

假设当前缓冲区位置开头的两个数字称为A和B,A是两位数字,B是三位数字。就结果所需的存储量而言,有两种可能的结果,即R <或者

AA+BBB+remainder -> RRR+remainder

AA+BBB+remainder -> RRRR+remainder

这意味着您的变量取决于结果的位数,是的,您可以将其基于resultLen(但它本身不是resultLen)。请注意,如果你向后移动,你需要填充你在缓冲区末尾留下的一些合适字符的间隙,或者跟踪缓冲区真正结束的位置。

不是将其余部分向后移动,而是将其保持在原位并将结果写在它之前的正确位置(除非你的作业明确要求你将其向后移动)。所以你拿

AA+BBB

并将其转换为

...DDD

..DDDD

其中圆点表示我们不再感兴趣的字符。只要您在while循环的每次迭代中更新了起始索引,那么这些字符就无关紧要了(摆脱{ {1}}循环)。如果你知道A,B和R的数字位数,这对你来说应该不会太困难。最后,当起始索引达到i时,跳出while循环。