решение выражения в буфере - PullRequest
1 голос
/ 05 июля 2011

Я пытаюсь создать функцию (в 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) -> (5) причина в том, что со временем будет написано больше функций для обработки умножения, деление и т. д. Вот в чем заключается мое основное разочарование - размещение результата вместо выражения и смещение буфера в нужное количество.

Ответы [ 2 ]

1 голос
/ 06 июля 2011

Обратите внимание, что

 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

, либо

AA+BBB+remainder -> RRRR+remainder

Это означает, что у вас есть переменное смещениев зависимости от того, сколько цифр имеет результат, да, вы можете основывать его на resultLen (но это не resultLen само по себе).Обратите внимание, что если вы вернетесь назад, вам нужно заполнить пробелы, которые вы оставляете в конце буфера, подходящим символом или отследить, где теперь находится реальный конец буфера.

Вместо того, чтобы сдвигать остаток назадЯ бы оставил его там, где он есть, и записал бы результат в правильном месте перед ним (если, конечно, ваше задание явно не просит вас сдвинуть его назад).Таким образом, вы берете

AA+BBB

и конвертируете его в

...DDD

или

..DDDD

, где точки представляют символы, которые нам больше не нужны.символы не будут иметь значения, пока вы обновляете начальный индекс на каждой итерации цикла while (избавьтесь от цикла i).Если вы знаете количество цифр, которые есть у A, B и R, это не должно быть слишком сложным для вас.Наконец, вырвитесь из цикла while, когда начальный индекс достигнет bufferLen.

1 голос
/ 06 июля 2011
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% как долго.

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