Как провести различие между однозначными и многозначными числами в виде символов в C? - PullRequest
0 голосов
/ 12 октября 2019

Итак, я читаю входные данные из стандартного ввода и должен вычислять арифметику из него. Например, мне может быть дано:

3+4
4+3
7+9

Который затем будет помещен в массив символов вроде этого:

{3+4;4+3;7+9}

Я хочу создать программу, которая будет принимать этот ввод иreturn:

{7;7;16}

Так как это из стандартного ввода в C, каждый элемент будет иметь тип char. Я создал следующий код для работы с такими массивами и возврата правильного результата:

char *int2string(int i, char *s)
{
    sprintf(s, "%d", i);
    return s;
}

        bufferlen = strlen(buffer);
        int result;
        for (i = 0; i < bufferlen; i++)
        {
            if (isNumeric(buffer[i]))
            {
                value1 = atoi(&buffer[i]);
                if (buffer[i + 1] == '+')
                {
                    if (isNumeric(buffer[i + 2]))
                    {
                        value2 = atoi(&buffer[i + 2]);
                        result = value1 + value2;
                        printf("This is the result: %d\n", result);
                        int2string(result, &buffer[i]);
                        for (int k = i + 1; k < bufferlen; k++)
                        {
                            buffer[k] = buffer[k + 2];
                        }
                        //bufferlen = bufferlen - 2;
                    }
                }
            }
        }

К сожалению, мой код работает только для ввода, состоящего из одного символа, и возвращает значение, состоящее только из одного символа,Если бы я запустил это:

34+22

Мой код возвращает следующее:

This is the result: 26
322;

Я считаю, что это происходит, потому что мой код может читать только один символ за раз ине может различить однозначные числа и числа, состоящие из более чем одной цифры. Есть ли способ, как я могу это исправить?

Ответы [ 2 ]

0 голосов
/ 12 октября 2019

Ваша проблема, я думаю, в том, что вы делаете что-то вроде

value1 = atoi(&buffer[i]);
if (buffer[i + 1] == '+')
    ...

В этом фрагменте индекс i "указывает" на то место в buffer, где вы в данный момент выполняете анализ,Вы верите (и правильно), что i "указывает" на первый из одного или нескольких цифровых символов. Вы звоните atoi, чтобы преобразовать эту цифру (цифры) в фактическое целое число. Пока все хорошо. Но затем вы проверяете buffer[i + 1], чтобы увидеть, есть ли после числа символ оператора. Это , где возникло неправильное предположение, что числа всегда имеют длину в одну цифру. Это то, что вам нужно исправить, чтобы правильно обрабатывать многозначные числа.

Лучший способ исправить это, я бы сказал, - использовать strtol вместо atoi. Наиболее очевидное различие между atoi и strtol заключается в том, что strtol сообщает вам, как далеко он продвинулся, сколько цифр он использовал. Он делает это, возвращая вам указатель на первый символ, который он не использовал.

Это означает, однако, что для использования strtol вам придется явно использовать указатели. Будет намного проще, если вы будете использовать указатель

char *p;

для перехода по buffer вместо индекса i. Но тогда вы можете сказать что-то вроде

char *endp;
value1 = strtol(p, &endp, 10);
p = endp;
if (*p == '+')
    ...

. Как это работает, strtol устанавливает endp для указания на первый символ, который он не использовал. Вот где вы хотите продолжить анализ, поэтому вы устанавливаете p на endp и продолжаете.

Здесь на самом деле происходит то, что strtol принимает указатель на указатель . Если вам пока не удобно работать с указателями, возможно, вы действительно не готовы думать об указателях на указатели, но, поверьте мне, это работает.

0 голосов
/ 12 октября 2019

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

int sum, len;
sscanf(buffer, "%d%n", &sum, &len); // get the first number

int number;
char op;

buffer += len;

// then pattern is: "operation""number"
while(sscanf(buffer, "%c%d", &op, &number) == 2) // while you can scan both operation and number
{
    if (op == '+')
        sum += number;
    else if (op == '-')
        sum -= number;
    ...
}

Подробнее о sscanf здесь .

...