C 在缓冲区中求解表达式

C 在缓冲区中求解表达式,c,parsing,C,Parsing,我试图创建一个函数(在C中)来解决一个放在缓冲区变量中的加法。到目前为止,它适用于产生一位数的方程式,但如果结果超过一位数,则会导致问题。。例如,如果我将2+3+5+2放入缓冲区,则输出102,而不是12。有人能指出我的错误在哪里以及我如何修复它们吗 这是我的密码: char buffer[50]; void *adder(void) { int bufferlen; int value1, value2; int startOffset, remainderOffse

我试图创建一个函数(在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;
    }

}
char缓冲区[50];
void*加法器(void)
{
int-bufferlen;
int值1、值2;
int STARTOFSET,剩余偏移量;
int i;
字符结果[10];
而(1)
{
startOffset=remainderOffset=-1;
value1=value2=-1;
bufferlen=strlen(缓冲区);
对于(i=0;i0)
缓冲区[k]=缓冲区[k+2];
其他的
缓冲区[k]=缓冲区[k+2];
printf(“A2缓冲区:%s\n”,缓冲区);
i=i-剩余偏移量;
startOffset=remainderOffset=-1;
value1=value2=-1;
}
}
}
}
打破
}
}
编辑:啊,对不起,忘记了额外的功能。此函数用于学校作业,isNumeric()和String2int()与isdigit()和atoi()完全相同,并提供给我们在函数中使用

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 */
}
编辑2:数字相加后,结果必须添加回表达式位置的缓冲区中,如:(2+3)->(5)原因是最终将写入更多函数来处理乘法、除法、和,这就是我的主要挫折所在——将结果替换为表达式,并将缓冲区向左移动适当的量

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

void *adder(void)
该函数不返回一个
void*
;它没有返回值。你可以考虑

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

接下来,在不初始化的情况下声明一些变量。将声明移动到循环中,并包括声明的初始化,即
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%的长度。

注意

 if(j > 0)
     buffer[k] = buffer[k+2];
 else
     buffer[k] = buffer[k+2];
执行相同的代码,而不考虑
j
的值。还要注意,
j
无论如何在代码中都不能是负数

您的缓冲区数组超出了边界。循环计数器
i
在每个循环结束时递增一,但您也在这样做

i = i - remainderOffset;
k
循环中多次。那肯定会给你一个否定的
i

此外,当您使用

 buffer[k] = buffer[k+2];
循环的时间为
k
bufferLen
,因此
k+2
在这里也是不受限制的

我不知道你为什么要把所有东西移回固定的两个位置?当然,这是假设您只添加了一位数字

想想这些问题,你就会发现你的错误所在。我同意其他人的看法,如果您可以利用现有代码,那么就这样做

编辑:回应您的评论

我假设将结果存储在缓冲区是任务的一部分?如果不是这样的话,只需在一个整数中跟踪它,一切都会大大简化。如果分配说明必须使用中间结果更新缓冲区,请注意以下事项:

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

AA+BBB+remainder -> RRR+remainder

这意味着您有一个可变的移位,取决于结果的位数,因此,是的,您可以基于
resultLen
(但它不是
resultLen
本身)。请注意,如果您向后移动,则需要使用一些合适的字符来填充在缓冲区末尾留下的间隙,或者跟踪缓冲区的实际结尾现在在哪里

我不会将余数向后移动,而是将它放在原处,并将结果写在它前面的正确位置(当然,除非你的作业明确要求你将其向后移动)。所以你要

AA+BBB+remainder -> RRRR+remainder
AA+BBB
...DDD
..DDDD