RPN калькулятор, используя связанный список

У меня проблемы с моим кодом. Кажется, он работает только на однозначное число Int. Я не знаю, как создать функцию, которая работала бы для int больше 9. Также я не знаю, как завершить программу, если строка пуста.

Вот мой код:

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

//stack type
struct node
{
    int head;
    int *array;
    unsigned capacity;
};

struct node* createNode();
int isEmpty();
char pop();
void push(struct node* stack, char op);
int evaluatePostfix();

int main()    {
    char exp[1000]; // = "5 1 2 + 4 * + 3 -";
    printf("Input string:\t");
    fgets(exp, 1000, stdin);
    for(int i = 1 ; i <= strlen(exp); i++) {
        if(exp[i] == '\n') {
            exp[i] = '\0';
        }
        else if (exp[0] == '\n') {
            printf("stack is empty\n");
            exit(0);
        }
    }
    printf ("%s = %d\n", exp, evaluatePostfix(exp));
    return 0;
}

struct node* createNode(unsigned capacity)  {
    struct node* stack = (struct node*) malloc(sizeof(struct node));

    if (!stack) return NULL;

    (*stack).head = -1;
    (*stack).capacity = capacity;
    (*stack).array = (int*) malloc((*stack).capacity *sizeof(int));

    if (!(*stack).array) return NULL;

    return stack;
}

int isEmpty(struct node *stack) {
    return (*stack).head == -1 ;
}


char pop(struct node* stack)    {
    if (!isEmpty(stack))
    return (*stack).array[(*stack).head--] ;
    return '$';
}


void push(struct node* stack, char op)  {
    (*stack).array[++(*stack).head] = op;
}

// The main function that returns value of a given postfix expression 
int evaluatePostfix(char* exp)  {

// Create a stack of capacity equal to expression size
    struct Stack* stack = createStack(strlen(exp));
    struct node *stack = createNode(strlen(exp));
    if (!stack) return -1;

// Scan all characters one by one

for (int i = 0; exp[i]; ++i){
    // If the scanned character is an operand or number,
    // push it to the stack.    
   if ((exp[i])== ' ') continue;
   else if (isdigit(exp[i]))
        push(stack, exp[i] - '0');


    //  If the scanned character is an operator, pop two
    // elements from stack apply the operator 
    else
    {
        int val1 = pop(stack);
        int val2 = pop(stack);
        switch (exp[i])
        {
         case '+': push(stack, val2 + val1); break;
         case '-': push(stack, val2 - val1); break;
         case '*': push(stack, val2 * val1); break;
         case '/': push(stack, val2/val1);   break;
        }
    }
}
return pop(stack);
}

1 ответ

Я не могу написать все для вас, но могу указать вам правильное направление. Во-первых, когда кто-то говорит "библиотечная функция XYZ() будет полезна для вас", тогда вы должны прочитать об этой функции на страницах руководства. Например, из оболочки Linux запустите: man atoi читать о atoi функция.

Для вашей конкретной задачи она сводится к разбору строк и преобразованию их в числа и операторы. Таким образом, некоторые полезные библиотечные функции:

  • strtok: Извлекает строковые токены с разделителями из более длинной строки. Вы можете использовать это, чтобы получить каждый из отдельных входов.
  • atoi: Это может преобразовать строковое представление числа в его целочисленный эквивалент. Не позволяет проверять ошибки.
  • strtol: Можно сделать так же, как atoi (и многое другое), а также позволяет проверять ошибки.

Имея в виду эту информацию, вот фрагмент кода, который может быть полезен для вас:

int evaluatePostfix(char* exp)
{
    char *token;
    long int number;

    /* strtok will keep extracting the next token delimited by space */
    while (token = strtok(exp, " ")) {

        /* Now parse the token and process it */
        if (is_operator(token)) {
            /* do operator processing */
        } else {
            number = strtol(token, NULL, 10);
            /* do number processing */
        }
    }

    /* strtok returns NULL when no more tokens. So
       we are done when the while loop exits */
}

Обратите внимание, что приведенный выше код не выполняет проверку ошибок на strtol, Вы, вероятно, хотите сделать это. Прочитайте справочные страницы для strtol чтобы понять, как для этого делается проверка ошибок.

Другие вопросы по тегам