i ve programmed a postfix calculator it woks fine until if make new calculation
e.g:
3+4*2
=11

new try
3+4*2
i get stack empty error

does anyboy knows why

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace postcalc
{
    public partial class Form1 : Form
    {
        Stack stack = new Stack();
        Stack revstack = new Stack();

        float result;
        float first,second;

        string temp;

        string lastnum;
        char[] ramy;
        //char[] calc;
        bool empty = true;
        

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
          
        }

        private void button1_Click(object sender, EventArgs e)
        {
            stack.Clear();
            revstack.Clear();

            ramy = textBox1.Text.ToCharArray();

            foreach (char c in ramy)
            {
                if (char.IsDigit(c))
                    lastnum = lastnum + c.ToString();
                else
                {
                   stack.Push(lastnum);
                   lastnum = "";
                    
                    if (empty)
                    {
                        revstack.Push(c);
                        empty = false;
                    }
                    else
                        check(c);
                 
                }

            }

            stack.Push(lastnum);
            lastnum = "";

            checkingIfThereOtherOperator(); // checking if there any other operations


            reversestack(); // reverse the stack


            // displaynig the postfix
            textBox2.Text = "";


            while (revstack.Count != 0)
            {
                temp = revstack.Pop().ToString();
                textBox2.Text = textBox2.Text + temp + " ";
                stack.Push(temp);
            }

            //Reversing the stack again
            while (stack.Count != 0)
                revstack.Push(stack.Pop());
            
            //calculate
            calculate();
            


        }

        private void calculate()
        {
            
            while (revstack.Count != 0)
            {
                lastnum = revstack.Pop().ToString();
                SeeWhatCanUDo();
            }

            textBox3.Text = stack.Pop().ToString();
               
        }

        private void SeeWhatCanUDo()
        {
            lastnum.ToCharArray();
           // MessageBox.Show(lastnum[0].ToString());
            if(char.IsDigit(lastnum[0]))
            {
                lastnum.ToString();
                stack.Push(lastnum);
                lastnum = "";
            }
            else
            {
                lastnum.ToString();
                result = claculate();
                stack.Push(result);
            }
            
        }

        private float claculate()
        {
            second = float.Parse(stack.Pop().ToString());
            first = float.Parse(stack.Pop().ToString());

            switch (lastnum)
            {
                case "+":
                    result =  first + second;
                    break;
                case "-":
                    result =  first - second;
                    break;
                case "*":
                    result = first * second;
                    break;
                case "/":
                    result =  first / second;
                    break;
            }

            return result;  
        }

  
        private void reversestack()
        {
            while (stack.Count != 0)
                revstack.Push(stack.Pop());

           
           
        }



        private void checkingIfThereOtherOperator()
        {
            while (revstack.Count != 0)
                    stack.Push(revstack.Pop());
        }



        private void check(char c)
        {
            switch (c)
            {
                case '+':
                  
                        while (revstack.Count != 0)
                            stack.Push(revstack.Pop());

                        revstack.Push(c);
                    
                    break;
                case '-':
                    while (revstack.Count != 0)
                        stack.Push(revstack.Pop());

                    revstack.Push(c);
                    break;
                case '*':

                    while (revstack.Count != 0)
                        if (revstack.Peek().ToString() == "*" || revstack.Peek().ToString() == "/")
                            stack.Push(revstack.Pop());
                        else
                            break;

                     revstack.Push(c);
                    break;
                case '/':
                    while (revstack.Count != 0)
                        if (revstack.Peek().ToString() == "*" || revstack.Peek().ToString() == "/")
                            stack.Push(revstack.Pop());
                        else
                            break;

                    revstack.Push(c);
                    break;
            }
        }
    }
}

Dani AI

Generated

The "Stack empty" on the second run is almost always a state-leak problem: parser/evaluator state that survives between button clicks produces a malformed postfix stream, so the evaluator tries to pop operands that were never pushed. was right that keeping parsing variables as class fields makes state leaks likely. is also on the right track—resetting the number buffer helps—but resetting only lastnum is not enough.

Practical fixes (quick and robust)

  • Quick patch: at the very start of the click handler reinitialize the parser/eval state: reset the operator flag to its initial value, empty the number buffer, and clear both stacks and numeric temporaries. Also avoid indexing lastnum[0] without checking length first (for example, if (!string.IsNullOrEmpty(lastnum) && char.IsDigit(lastnum[0]))) and use float.TryParse when converting tokens. Those checks prevent exceptions from empty tokens or malformed postfix.
  • Better design: make the operator stack, the postfix token list, and the evaluation stack local variables inside the button handler (or into a dedicated parser class). Local, strongly typed structures (for example Stack<float> for operands and List<string> for the postfix) eliminate cross-run leaks and make bugs much easier to find.

Algorithm and debugging tips

  • Separate tokenization, infix->postfix (shunting-yard), and postfix evaluation. Keep postfix in a list so it can be printed (debug) before evaluation—if the list misses a number, the evaluator will fail and the bug is in tokenization.
  • Before popping two operands for an operator always check evalStack.Count >= 2 and provide a clear error if not. Use TryParse and explicit error messages rather than letting the runtime throw "Stack empty."

Summary note: reset any per-run flags and buffers or move them to local scope. That will eliminate the intermittent second-run failure and make the code more maintainable.

Recommended Answers

All 2 Replies

Your problem is that you use variables global to your class instead of passing them from function to function. The result is that it's easy for previous states of your program to leak all over the place.

Set your lastnum into null once you wanna try again.
<anyway thanks for the program> i copied a part of it for my assignment.

cheers...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.