Code that should receive an arithmetic expression in infix (common) notation for postfix notation (Polish reverse). For example, when receiving (A + B C) it should print ABC +. The problem with my code is that when it receives "(A + B C)" it prints "ABC". Upon receiving "(A (B + C) / D-E)" it prints "ABCDE". In other compilers, the squares do not appear, but the return remains wrong. It gives no error, nor does it show any warning. I think it gives segfault somewhere, but since I'm using repl.it to compile, I do not have access to the debug.
The code is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 256
typedef enum {FALSE, TRUE} BOOL;
typedef int TIPOCHAVE;
typedef struct {
TIPOCHAVE chave;
} REGISTRO;
typedef struct {
REGISTRO a[MAX];
int topo;
} PILHA;
REGISTRO criarReg(TIPOCHAVE chave) {
REGISTRO reg;
reg.chave = chave;
return reg;
}
void inicializar(PILHA *pilha) {
pilha->topo = 0;
}
int vazia(PILHA *pilha) {
return pilha->topo == 0;
}
int cheia(PILHA *pilha) {
return pilha->topo == MAX;
}
void exibir(PILHA *pilha) {
int i = 0;
printf("Pilha: [");
for (i=0; i<pilha->topo; i++) {
printf("%d", pilha->a[i].chave);
if (i < pilha->topo-1)
printf(", ");
}
printf("] <-- topo\n");
}
int empilha(REGISTRO elem, PILHA *pilha) {
if (cheia(pilha)) {
return FALSE;
}
pilha->a[pilha->topo] = elem;
pilha->topo++;
return TRUE;
}
int desempilha(PILHA *pilha, REGISTRO *elem) {
if (vazia(pilha))
return FALSE;
*elem = pilha->a[pilha->topo-1];
pilha->topo--;
return TRUE;
}
void esvaziar(PILHA *pilha) {
pilha->topo = 0;
}
int topo(PILHA *pilha, REGISTRO *elem) {
if (vazia(pilha))
return FALSE;
*elem = pilha->a[pilha->topo-1];
return TRUE;
}
//função para checar se o caractere da string é um operando
int operando(char ch)
{
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
}
//função que determina a prioridade de cada operador
//valor retornado maior é igual a operador de prioridade maior
int prioridade(char ch)
{
switch(ch)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
}
return -1;
}
//função que converte de infixa para posfixa
int inpos(char *expr)
{
PILHA pilha;
inicializar(&pilha);
int i, aux;
REGISTRO elem;
for (i = 0, aux = 0; expr[i] != '#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 256
typedef enum {FALSE, TRUE} BOOL;
typedef int TIPOCHAVE;
typedef struct {
TIPOCHAVE chave;
} REGISTRO;
typedef struct {
REGISTRO a[MAX];
int topo;
} PILHA;
REGISTRO criarReg(TIPOCHAVE chave) {
REGISTRO reg;
reg.chave = chave;
return reg;
}
void inicializar(PILHA *pilha) {
pilha->topo = 0;
}
int vazia(PILHA *pilha) {
return pilha->topo == 0;
}
int cheia(PILHA *pilha) {
return pilha->topo == MAX;
}
void exibir(PILHA *pilha) {
int i = 0;
printf("Pilha: [");
for (i=0; i<pilha->topo; i++) {
printf("%d", pilha->a[i].chave);
if (i < pilha->topo-1)
printf(", ");
}
printf("] <-- topo\n");
}
int empilha(REGISTRO elem, PILHA *pilha) {
if (cheia(pilha)) {
return FALSE;
}
pilha->a[pilha->topo] = elem;
pilha->topo++;
return TRUE;
}
int desempilha(PILHA *pilha, REGISTRO *elem) {
if (vazia(pilha))
return FALSE;
*elem = pilha->a[pilha->topo-1];
pilha->topo--;
return TRUE;
}
void esvaziar(PILHA *pilha) {
pilha->topo = 0;
}
int topo(PILHA *pilha, REGISTRO *elem) {
if (vazia(pilha))
return FALSE;
*elem = pilha->a[pilha->topo-1];
return TRUE;
}
//função para checar se o caractere da string é um operando
int operando(char ch)
{
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
}
//função que determina a prioridade de cada operador
//valor retornado maior é igual a operador de prioridade maior
int prioridade(char ch)
{
switch(ch)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
}
return -1;
}
//função que converte de infixa para posfixa
int inpos(char *expr)
{
PILHA pilha;
inicializar(&pilha);
int i, aux;
REGISTRO elem;
for (i = 0, aux = 0; expr[i] != '%pre%'; i++)
{
//se o caractere escaneado for um operando, colocar no output.
if (operando(expr[i]))
expr[aux++] = expr[i];
//se o caractere escaneado for um '(', empilhar.
else if (expr[i] == '(')
empilha(criarReg(expr[i]), &pilha);
//se o caractere escaneado for um ')', desempilhar e mostrar até
//um '(' ser achado.
else if (expr[i] == ')')
{
while (!vazia(&pilha) && topo(&pilha, &elem) != '(')
expr[aux++] = desempilha(&pilha, &elem);
if (!vazia(&pilha) && topo(&pilha, &elem) != '(')
return 0; //expressão inválida
else
desempilha(&pilha, &elem);
}
else //um operador é encontrado
{
while (!vazia(&pilha) && prioridade(expr[i]) <= prioridade(topo(&pilha, &elem)))
expr[aux++] = desempilha(&pilha, &elem);
empilha(criarReg(expr[i]), &pilha);
}
}
//desempilha todos os elementos da pilha
while (!vazia(&pilha))
expr[aux++] = desempilha(&pilha, &elem);
expr[aux++] = '%pre%';
printf("%s", expr);
}
int main()
{
char expr[60];
fgets(expr, 60, stdin);
inpos(expr);
return 0;
}
'; i++)
{
//se o caractere escaneado for um operando, colocar no output.
if (operando(expr[i]))
expr[aux++] = expr[i];
//se o caractere escaneado for um '(', empilhar.
else if (expr[i] == '(')
empilha(criarReg(expr[i]), &pilha);
//se o caractere escaneado for um ')', desempilhar e mostrar até
//um '(' ser achado.
else if (expr[i] == ')')
{
while (!vazia(&pilha) && topo(&pilha, &elem) != '(')
expr[aux++] = desempilha(&pilha, &elem);
if (!vazia(&pilha) && topo(&pilha, &elem) != '(')
return 0; //expressão inválida
else
desempilha(&pilha, &elem);
}
else //um operador é encontrado
{
while (!vazia(&pilha) && prioridade(expr[i]) <= prioridade(topo(&pilha, &elem)))
expr[aux++] = desempilha(&pilha, &elem);
empilha(criarReg(expr[i]), &pilha);
}
}
//desempilha todos os elementos da pilha
while (!vazia(&pilha))
expr[aux++] = desempilha(&pilha, &elem);
expr[aux++] = '%pre%';
printf("%s", expr);
}
int main()
{
char expr[60];
fgets(expr, 60, stdin);
inpos(expr);
return 0;
}
What could be wrong?