I'm writing a code to convert postfix to infix. but when i try to print the stack elements to check it it's not showing any thing. in the push
function it prints the top element, but the display
function only shows the top element no matter what. and there is segmentation fault after the line strcat(nn,y)
.The input i tried was 09+
.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX 20
char *stk[MAX], a[MAX];
int t = -1;
void push(char x[]);
void pop();
void display();
int main()
{
int i = 0;
char *x, *y, nn[MAX];
printf("enter expression:");
gets(a);
while (a[i] != '\0')
{
if (isdigit(a[i]))
{
push((char [2]){ a[i], '\0' });
}
else
{
display();
pop();
x = stk[t];
pop();
y = stk[t];
strcpy(nn, "");
strcat(nn, "(");
strcat(nn, y);
strcat(nn, (char [2]){ a[i], '\0' });
strcat(nn, x);
strcat(nn, ")");
push(nn);
}
i++;
}
printf("%s", stk[0]);
}
void push(char x[])
{
t = t + 1;
stk[t] = x;
printf("curtop %d:%s\n", t, stk[t]);
}
void pop()
{
t = t - 1;
}
void display()
{
printf("%s:%s", stk[t], stk[t - 1]);
}
1条答案
按热度按时间ohtdti5x1#
我将重申这些评论,加上一些参考资料,并补充一些我自己的想法。
你应该做的第一件事是阅读Why is the
gets
function so dangerous that it should not be used?gets
被从C11语言中删除,任何半现代的工具链都不应该包括它:fgets
是建议的替代项。请使用它。两者均为compound literals
这意味着每个对象的lifetime在它们各自的封闭块结束时结束。
因此,您正在将一个即将出现的dangling pointer推送到堆栈上。
这是Undefined Behaviour的一个示例。
以下
重复将指向
nn
的第一个元素的同一指针推入堆栈。该指针值始终相同,并且始终指向数组的 * 当前 * 内容,该内容不断更改。这两个问题都可以通过使用dynamic memory创建推入堆栈的字符串的副本来解决。
nn
(中缀表达式缓冲区)与a
(后缀表达式缓冲区)大小相同,但两者都太小。请记住,要在缓冲区中存储字符串,缓冲区的大小必须至少为字符串的长度加1(对于null terminating byte)。
后缀表达式
的字符串长度为13,适合
a
。其字符串长度为25。这不适用于
nn
,并且strcat
无法防止缓冲区溢出。这将是Undefined Behaviour的另一个示例。
作为设计的一个要点
是笨拙的。
虽然文件作用域变量(全局变量)的使用和围绕它们的函数是一个非常common way的数据结构,但您仍然应该致力于实现更接近abstract data type的东西。
pop
应该 * 返回 * 堆栈的最顶层元素,作为pop
函数的 * 用户 *,您不应该关心如何管理它,只应该关心它是否按预期行为。下一步是删除文件作用域变量,以便程序中可以同时存在多个堆栈。
下面是一个粗略的示例程序,它解决了所讨论的大多数问题。注意,它解析输入的方式略有不同,使用whitespace as a delimiter。它遵循括号的规则。
它不验证操作数或生成的表达式。操作数可以长于一个字符。