Инфикс для обратной польской нотации

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

typedef struct stack
 {
   char a[400];
   int top;
 }
 stack;
 stack s;
 void push(char *,int);
 int pop();

 int main()
  {
    char x[400];
    int len,i,y;
    puts("Enter string");
    scanf("%s",x);
    len=strlen(x);
    for(i=0;i<len;i++)
      {
//considering user is entering only the small alphabets 

      if((x[i])>=97&&x[i]<=122)
      printf("%s",x[i]);

      else
//if encountering the operator then pushing it into stack

      if(x[i]=='/'||x[i]=='*'||x[i]=='+'||x[i]=='-')
        {
        push(x,i);
        }

      else if(x[i]=='(')
      continue;
//When encountering the ')' then popping the operator

      else
        {
        y=pop();
        printf("%c",y);
        }
    }

  return 0;
 }

Передача массива и его размера в качестве аргумента

void push(char *x,int i)
{
  stack s;
  s.top++;
  s.a[s.top]=x[i];
}

Возврат всплывающего оператора при обнаружении ")"

int pop()
 {
   stack s;
   int temp;
   temp=s.a[s.top];
   s.top--;
   return temp;
 }

person LEO NARDO    schedule 24.03.2015    source источник
comment
Где происходит сбой?   -  person user253751    schedule 24.03.2015
comment
при вводе входного выражения   -  person LEO NARDO    schedule 24.03.2015


Ответы (1)


В вашем коде

printf("%s",x[i]);

неправильно. То, что вы хотите, это

printf("%c",x[i]);

Согласно стандарту C11, глава 7.21.6.1, спецификатор формата %s

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

но здесь x[i] имеет тип char.

Кроме того, из пункта 9,

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

Итак, ваш код вызывает неопределенное поведение.

Затем для обеих функций, push() и pop(), вы определяете локальную переменную stack s; который создается при каждом вызове этих функций и уничтожается по окончании выполнения. Вместо этого вы можете использовать переменную gloabl. Удалите локальные переменные, они не нужны.

Кроме того, для обеих функций вы используете значение s.top в качестве индекса массива s.a, но без какой-либо проверки границ. Прежде чем использовать значение s.top в качестве индекса, следует проверить значение индекса массива для случая полного стека (push()) и случая пустого стека (pop()). Приращение и уменьшение s.top также должны быть помещены под галочкой.


РЕДАКТИРОВАТЬ:

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


Примечание. Согласно стандарту C, int main() должно быть int main(void).

person Sourav Ghosh    schedule 24.03.2015
comment
Теперь он печатает только первый алфавит, а затем сбой - person LEO NARDO; 24.03.2015
comment
да, теперь он работает, но в нем есть логическая ошибка, операторы, которые не являются частью фигурных скобок, не печатаются с ошибкой, например (a + b) * (c + d), печатает ab + cd + - person LEO NARDO; 24.03.2015
comment
а что касается удаления части локальной переменной, имеют ли локальные переменные больший приоритет, чем глобальные переменные? - person LEO NARDO; 24.03.2015
comment
@LEONARDO Да, локальные переменные всегда затеняют глобальные переменные. - person Sourav Ghosh; 24.03.2015
comment
@LEONARDO, а что касается логической части, после того, как вы закончите синтаксический анализ всех входных данных, вы должны проверить, осталось ли что-нибудь в стеке или нет. как в псевдокоде, while (s.top !=0) { y = pop(); printf("%c", y) ; }. Попробуйте это и сообщите нам результат. - person Sourav Ghosh; 24.03.2015
comment
Да, теперь это работает, и мне не нужно проверять порядок старшинства. - person LEO NARDO; 24.03.2015