2016-11-20 2 views
0

Я пытаюсь создать простой парсер RPN, который принимает только одноразрядные значения и операторы + - * /. Я использовал стек для хранения исходного ввода, но у меня возникают проблемы с печатью вывода.RPN вывод неверных данных: C

Когда я запускаю отладку, он выдает сообщение об ошибке «Программный сигнал SIGSEGV, Ошибка сегментации», привязанный к строке 94. Вход, который я использовал в этом случае, был 11+. Первоначально я полагал, что это связано с тем, что всплывающие данные не были сохранены правильно, поэтому я создал T1 и T2, чтобы действовать как временные переменные. Однако это не устраняет проблему. Я также попытался одновременно развязать команды push и pop из eachother; до сих пор нет успеха.

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

файл lib.c здесь:

#include "defs.h" 
//Initialising the stack 
TopStack *initTOS() 
{ 
TopStack *pTopStack; 
pTopStack=(TopStack*)malloc(sizeof(TopStack)); 
return(pTopStack); 
} 

//Pushing an element onto the stack 
void push(TopStack *ts, int val) 
{ 
if(ts->num==0) 
{ 
    Stack *pNewNode; 
    pNewNode=(Stack*)malloc(sizeof(Stack)); 
    pNewNode->val=val; 
    pNewNode->next=NULL; 
    ts->top=pNewNode; 
    ts->num++; 
} 
else if(ts->num!=0) 
{ 
    Stack *pNewNode; 
    pNewNode=(Stack*)malloc(sizeof(Stack)); 
    pNewNode->val=val; 
    pNewNode->next=ts->top; 
    ts->top=pNewNode; 
    ts->num++; 
} 
} 

int pop(TopStack *ts) 
{ 
if(ts->num==0) 
    { 
     printf("Can't pop, stack is empty!\n"); 
     exit(1); 
    } 
else{ 
     Stack *pTemp = ts->top; 
     int RemovedValue; 
     RemovedValue=pTemp->val; 
     ts->top=pTemp->next; 
     ts->num--; 
     free(pTemp); 
     return (RemovedValue); 
    } 
} 

void testStack(TopStack *ts) 
{ 
int RemovedValue; 
push(ts,1); 
push(ts,2); 
printf("the popped value was %i\n",pop(ts)); 
printf("the popped value was %i\n",pop(ts)); 
} 

void parseRPN(TopStack *st) 
{ 
char Input[50]; 
int i; 
do{ 
    printf("please enter an expression in single-digit integers using RPN:\n"); 
    scanf("%49s",&Input); 
    if (strlen(Input)>=50) 
     { 
      printf("that expression was too large for the RPN engine to handle! please break it down into smaller sub-tasks.\n"); 
      fflush(stdin); 
      continue; 
     } 
    break; 
}while(true); 

for (i=0; Input[i] != '\0';i++) 
    { 
     if ((isdigit(Input[i])==0) && ((Input[i] != '+') && (Input[i] != '-') && (Input[i] != '*') && (Input[i] != '/'))) 
     { 
      printf("Error: Invalid operand to RPN\nExiting...\n"); 
      exit(1); 
     } 
     else printf("accepted %c for processing...\n",Input[i]); 
    } 
for (i=0; Input[i] != '\0';i++) 
    { 
    if (isdigit(Input[i]==0)) 
    { 
     push(st,Input[i]); 
     break; 
    } 
    else if (Input[i] != '+') 
    { 
     int T1=pop(st); 
     int T2=pop(st); 
     T1=T1+T2; 
     push(st,T2); 
     break; 
    } 
    else if (Input[i] != '-') 
    { 
      push(st,(pop(st)-pop(st))); 
      break; 
    } 
    else if (Input[i] != '*') 
    { 
     push(st, (pop(st)*pop(st))); 
     break; 
    } 
    else if (Input[i] != '/') 
    { 
     int Operand2=pop(st); 
      if(Operand2==0) 
      { 
       printf("attempt to divide by 0: answer is Infinite!\n"); 
       exit(0); 
      } 
      else 
      { 
       push(st,pop(st)/Operand2); 
       break; 
      } 
    } 
    } 
} 

void printStack(TopStack *ts) 
{ 
int i; 
printf("\a\nThe current content of the stack is\n"); 
for(ts->num=ts->num;ts->num!=0;ts->num--) 
{ 
    printf("%i",ts->top->val); 
    break; 
} 
} 

Вот defs.h (я не могу изменить это как часть задания, оно было дано мне):

#include <stdio.h> 
#include <stdlib.h> 
#include <ctype.h> 
#include <assert.h> 
#include <stdbool.h> 

#define MAX_EXPR 50 


//struct that contains stack's element 

typedef struct stack_elem{ 
int val; 
struct stack_elem *next; 
} Stack; 

//struct that contains the pointer to the top of the stack 

typedef struct{ 
int num;//num of elements in stack 
Stack *top;;//top of stack 
} TopStack; 

//ts=pointer to the top of stack, val=element to push 

void push(TopStack *ts, int val); //push element on the stack 

//prints the elements in the stack 

void printStack(TopStack *ts); 

// initialize the structure that will point to the top of the stack 

TopStack * initTOS();

// a simple test for the stack 

void testStack(TopStack *ts); 

// ts=pointer to the top of stack 

int pop(TopStack *ts);//returns element from top of stack 
// simple parser function for RPN expressions that assumes numbers have only one digit 

void parseRPN(TopStack *st); 

// empties the stack using the pop operation 

void emptyStack(TopStack *ts); 

// performs the operation defined by character op on the elements on top of stack 

void performOp(TopStack *st, char op); 

и вот main.c:

#include "defs.h" 

int main() 
{ 
TopStack *tp; 

tp=initTOS();// initialize the top of stack structure 
// testStack(tp);// this function tests your stack 
parseRPN(tp); 
printStack(tp); 
return EXIT_SUCCESS; 
} 
+0

Первая проблема: в 'initTOS()' функцию, после выделения 'TopStack * pTopStack;', необходимо инициализировать как 'Int num' и' Стек * верх'. Добавьте 'pTopStack-> num = 0;' и 'pTopStack-> top = NULL;'. ** ПРЕДУПРЕЖДЕНИЕ: ** в 'printStack()' функция, for-loop настолько невероятна 'for (ts-> num = ts-> num; ts-> num! = 0; ts-> num--) '!!!! –

+0

У меня никогда не было проблем с инициализацией стека, когда я тестировал его с помощью функции testStack, но я добавил его в целях безопасности. Любые предложения о невозможном цикле for()? Я думаю, что здесь проблема ... – Thefoilist

+0

При тестировании исходного кода на '' 11 + '', я получаю **« Не могу поп, стек пуст! »**, потому что я предполагаю в RPN, перед добавлением номер необходимо добавить в стек один номер. –

ответ

1

Где смотреть в исходном коде, я обнаружил следующие ошибки:

Ошибка 1: В parseRPN(), А серия ошибок в if-состоянии isdigit().

if (isdigit(Input[i])!=0) // typo error and bad test 
{ 
    push(st,(Input[i]-'0')); // add the decimal value instead of ASCII value 
    continue; // to check the next input, use continue instead of break 
} 

Вместо

if (isdigit(Input[i]==0)) 
{ 
    printf("push(%c),",Input[i]); 
    push(st,(Input[i]-'0')); 
    break; 
} 

Ошибка 2: В parseRPN(), ряд ошибок в операторе "+".

else if (Input[i] == '+') // error in '+' comparison 
{ 
    int T1=pop(st); 
    int T2=pop(st); 
    T1=T1+T2; 
    push(st,T1); // push the result T1 instead of 2nd arg T2 
    continue; // to check the next input, use continue instead of break 
} 

Вместо

else if (Input[i] != '+') 
{ 
    int T1=pop(st); 
    int T2=pop(st); 
    T1=T1+T2; 
    push(st,T2); 
    break; 
} 

Ошибка 3: В parseRPN(), ряд ошибок в "-" оператора.

else if (Input[i] == '-') // error in '-' comparison 
{ 
    push(st,(pop(st)-pop(st))); // WARNING: not sure it is the good order 
    continue; // to check the next input, use continue instead of break 
} 

Ошибка 4: В parseRPN(), ряд ошибок в "*" оператора.

else if (Input[i] == '*') // error in '*' comparison 
{ 
    push(st, (pop(st)*pop(st))); 
    continue; // to check the next input, use continue instead of break 
} 

Ошибка 5: В parseRPN(), ряд ошибок в операторе "/".

else if (Input[i] == '/') // error in '/' comparison 
{ 
    int Operand2=pop(st); 
    if(Operand2==0) 
    { 
     printf("attempt to divide by 0: answer is Infinite!\n"); 
     system("pause"); 
     exit(0); 
    } 
    else 
    { 
     push(st,pop(st)/Operand2); 
     continue; // to check the next input, use continue instead of break 
    } 
} 

Ошибка 6: В printStack(), заменив для цикла на некоторое время, чтобы отобразить все значения в стеке.

Stack *pTemp; 

pTemp = ts->top; // start of stack 
while (pTemp!=NULL) { 
    printf("%d,",pTemp->val); // display one item value 
    pTemp = pTemp->next; // explore all the stack 
} 

Вместо

for(ts->num=ts->num;ts->num!=0;ts->num--) 
{ 
    printf("%i",ts->top->val); 
    break; 
} 
+0

Это решает ошибку, с которой я столкнулся, но была немного осторожна, так как она также печатала много мусора после реального результата. Благодаря! :) – Thefoilist

+0

Возможно, вам нужно больше кофеина !!! –

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