顺序栈实现计算器 有错 求帮忙解决

来源:互联网 发布:约瑟夫环java数组 编辑:程序博客网 时间:2024/04/28 17:35
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define S 100


typedef struct stack_ch
{
    char ch[S];
    int top;
}STA_CH;


typedef struct sta_num
{
    int num[S];
    int top;
}STA_NUM;




STA_CH *C;
STA_NUM *N;




void init_ch()        //初始化字符栈
{
    C = (STA_CH *)malloc(sizeof(STA_CH));
    C->top = -1;
}
void push_ch(char ch)    //字符进栈
{
    C->ch[++ C->top] = ch;


}
char pop_ch()      // 字符出栈
{   
    char ch;
    ch =  C->ch[C->top--];
    return ch;
}


void init_num()    //初始化数据栈
{
    N = (STA_NUM *)malloc(sizeof(STA_NUM));
    N->top = -1;
}
void push_num(int n)  //数据压栈
{
    N->num[++ N->top] = n;
    printf("n=%d\n",n);
}
int pop_num()    // 数据出栈
{   
    int tmp = 0;
    tmp = N->num[N->top --];
    return tmp;
}


char gettop()    //获得栈顶字符
{
    char c;
    c = C->ch[C->top];
    return c;
}


int empty_stack()  // 判断字符栈是否为空
{
    return C->top;
}


char *trans_last(char opt[])   //将中缀表达式转换成后缀表达式 只使用符号栈
{
    init_ch();
    int o = 0;
    int l = 0;
    char out;
    printf("opt=%s\n",opt);
    char *last = (char *)malloc(sizeof(char));


    while(opt[o] != '\0')
    {
        switch(opt[o])
{
   case '+':   //遇到 + -  低级
   case '-':
   
            while(empty_stack() != -1 && gettop() != '(')
    {
                              //只有栈不为空 或 栈顶为 ( 时 将栈顶任意运算符
                              //存放到后缀表达式中
       last[l] = pop_ch();
       l ++;
    }
                     push_ch(opt[o ++]);        // 否则一直将+ 或- 压栈
            break;


   case '*':   //遇到 * /  中级
   case '/':
   
             while(empty_stack() != -1 && (gettop() == '*' 
     || gettop() == '/'))    //栈不为空 或 栈顶为 * / 时  
                            //将栈顶运算符存放到后缀表达式中
     {
         last[l] = pop_ch();
         l ++;
     }
     push_ch(opt[o ++]);   //否则即 栈顶为+ - ( 时 将*或/运算符压栈
             break;


   case '(':   //处理括号  最高级
            push_ch(opt[o++]);
    break;


   case ')':    
            out = pop_ch();     //遇到右括号不入栈 取栈顶元素
            while(empty_stack() != -1 && out !='(') //当栈不为空 栈顶不是左括
    {
        last[l ++] = out;       // 将栈顶的运算符存放到后缀表达式中直到遇
                         out = pop_ch();         // 到左括号或者栈空
    }
    l ++;
            break;


   default : 
   
            while(opt[o] >= '0' && opt[o] <= '9' && opt[o] != '\0')  //遇到数字直接送入后缀表达式
    {
   
        last[l ++] = opt[o ++];      
    }
    last[l ++] = ' ';    //当opt 不是数字时在插入一个格 以便转换成整数时使用
            break;


}
    } 
    while(empty_stack()!=-1)    // 将剩余的字符全部存放到后缀表达式
    {
        last[l++] = pop_ch();   
    }
    last[l]='\0';
    return last;
}


int count_value(char *ptr)      //转换后缀表达式并且计算值
{
    init_num();
    //ptr = (char *)malloc(sizeof(char));
    int p = 0;    
    int result = 0;
    while(ptr[p] != '\0')
    {
        if( ptr[p] >= '0' && ptr[p] <= '9')
        {   
   int num = 0;
   while(ptr[p] != ' ')
   {
                num = num * 10 + ptr[p++] - '0';
   }
   p ++;
   printf("num=%d\n",num);
   push_num(num);
        }
        else
{
   if(ptr[p] !=' ')
   {
                int b = pop_num();
                int a = pop_num();
                printf("%d%c%d=",a,ptr[p],b);
                switch(ptr[p])
                {
                    case '+':result = a + b;break;
           case '-':result = a - b;break;
                    case '*':result = a * b;break;
           case '/':result = a / b;break;
                }
push_num(result);
printf("%d\n",result);
   }
   p ++;
        }
    }
    return pop_num();
}


int main()
{
   char input_opt[S];
   while(1)
   {
       char *ret = (char *)malloc(sizeof(char));
       int result;
       printf("please input the equation:\n");
       scanf("%s",input_opt);
       printf("input = %s\n",input_opt);
       
       ret = trans_last(input_opt);
       
      
       result = count_value(ret);
       printf("result = %d\n",result);
       printf("end\n");
       ret = NULL;
   }

   return 0;

}



Linux 下运行结果

}

当连续输入超过五个操作数的时候  第五个操作数 出现乱码 


当输入的表达式有 括号的时候 会出现段错误在 ch =  C->ch[C->top--]; 这一句

看见的大神给解决一下