2015-05-04 3 views
-1

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

Вот мой код:

#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); 
} 
+0

Используйте 'atoi' или' strtol' для преобразования каждого числа ascii в int/long. Вместо разбора одной цифры вручную. – kaylum

+0

Как я точно это сделаю? Мне жаль, что я еще не знаком с этими функциями – pixiedust27

ответ

0

Я не могу написать все это для вас, но может направить вас в правильном направлении. Во-первых, когда кто-то говорит, что «библиотечная функция 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, чтобы понять, как выполняется проверка ошибок.

Смежные вопросы