masterofcatastrophe masterofcatastrophe - 1 month ago 22
C# Question

Stack is empty ...Why?

im working on a c#program that involved stack and queue. the queue Enqueues the input string, and dequeues it as the stack operations are done on the input from the queue in the mean time.

now what is happening is in the checkMatch(), the program gives an exception error that says the Stack is empty.
Ive used the debugging/step over and I see the Stack is truly empty in the checkMatch function, and I dont understand why.
Ive done the same program in c++ to test it out, and in c++ i dont get this error at all, in fact, I get the output I desire.

but after a long research throughout the day, and trying a bunch of things, including shallow copy, cloning, etc.. i still cant seem to get the stack to contain something by the time the program enters the checkMatch function. during my debugging activity, ive realized that the stack and input are getting reset in the checkMatch function, hence why I am receiving this stack empty exception.

here is the code:

public static void loadtheInput(Queue<string> input)
{
input.Enqueue("A");
input.Enqueue("B");
input.Enqueue("C");
input.Enqueue("D");
}

public static void printtheLine(StreamWriter DisplayOutTxt, Queue<string> sameMatch, Stack<string> stack, Queue<string> input, string operations)
{
string returnMatched = "";
string returnStack = "";
string returnInput = "";

if (stack.Count == 0) //if stack is empty, printtheLine so DisplayOutTxt the table header
{
stack.Push("A");
stack.Push("C");
}
returnMatched = printQueue(matched);
returnStack = printStack(stack);
returnInput = printQueue(input);
}

public static string printStack(Stack<string> stack)
{
string DisplayOutTxt = "";
while (stack.Count > 0)
{
DisplayOutTxt += stack.Peek();
stack.Pop();
}
return DisplayOutTxt;
}

private static string printQueue( Queue<string> queue)
{
string DisplayOutTxt = "";

if (queue.Count == 0) //if the queue is empty
{
DisplayOutTxt = " "; //set DisplayOutTxt to a space
}
else
{
while (queue.Count > 0) //queue not empty
{
DisplayOutTxt += queue.Peek(); //concat front of queue to DisplayOutTxt
queue.Dequeue(); //dequeue the front string
}
}
return DisplayOutTxt;
}

public static void checkMatch(StreamWriter DisplayOutTxt, Queue<string> sameMatch, Stack<string> stack, Queue<string> input, ref string operations)
{
printtheLine(DisplayOutTxt, sameMatch, stack, input, operations); //print line of DisplayOutTxt

//here is where i start facing the problem. stack (and input) are both empty once they step into this checkMatch function!
//I think its a reference issue, but i just cant figure out what to do after everything Ive tried

if (stack.Peek() == input.Peek()) //if the next stuff in stack and input match each other
{
// some code is here
}
}

static int Main()
{
StreamWriter DisplayOutTxt = new StreamWriter("output.txt");

Queue<string> sameMatch = new Queue<string>();
Stack<string> stack = new Stack<string>();
Queue<string> input = new Queue<string>();

string operations = "";
loadtheInput(input); //load input into input queue and load all productions into parse table

while (input.Count > 0) //while input vector is not empty
{
checkMatch(DisplayOutTxt, sameMatch, stack, input, ref operations); //call function to check for sameMatch stuff
}
DisplayOutTxt.Flush();
DisplayOutTxt.Close();
return 0;
}


heres an image of some debugging/stepover i did to determine the stack count by the time the checkMatch function was entered

heres the exception error image

Answer

In your printStack function you are clearing the stack. By looping through and popping each item.

Refer to here how you can print your stack items without popping them.

In C# the Stack parameter will be a reference type, so modifying it in a function will mutate the original Stack. But, as the Stack implements IEnumerable, you can enumerate the items without modifying the original.

You could use something like this

public static string printStack(IEnumerable<string> stack)
{
    string DisplayOutTxt = "";

    foreach (var obj in stack)
    {
        DisplayOutTxt += obj;
    }

    return DisplayOutTxt;
}

But far more easier would be to do

returnStack = string.Join("", stack);