how to print out all elements in a std::stack or std::queue conveniently

73,964

Solution 1

I've written a snippet to do that for debugging. For example:

std::stack<int> s; // works with std::queue also!
s.push(1);
s.push(2);

std::cout << s; // [ 1, 2 ]

Please forgive me for this hackish code! but this is what I've written months ago:

#include <stack>
#include <queue>
#include <ostream>

template <class Container, class Stream>
Stream& printOneValueContainer
    (Stream& outputstream, const Container& container)
{
    typename Container::const_iterator beg = container.begin();

    outputstream << "[";

    while(beg != container.end())
    {
        outputstream << " " << *beg++;
    }

    outputstream << " ]";

    return outputstream;
}

template < class Type, class Container >
const Container& container
    (const std::stack<Type, Container>& stack)
{
    struct HackedStack : private std::stack<Type, Container>
    {
        static const Container& container
            (const std::stack<Type, Container>& stack)
        {
            return stack.*&HackedStack::c;
        }
    };

    return HackedStack::container(stack);
}

template < class Type, class Container >
const Container& container
    (const std::queue<Type, Container>& queue)
{
    struct HackedQueue : private std::queue<Type, Container>
    {
        static const Container& container
            (const std::queue<Type, Container>& queue)
        {
            return queue.*&HackedQueue::c;
        }
    };

    return HackedQueue::container(queue);
}

template
    < class Type
    , template <class Type, class Container = std::deque<Type> > class Adapter
    , class Stream
    >
Stream& operator<<
    (Stream& outputstream, const Adapter<Type>& adapter)
{
    return printOneValueContainer(outputstream, container(adapter));
}

You can stream std::stack and std::queue just like any other supported type!

Solution 2

You can't iterate through a stack or a queue. In fact, SGI's documentation says this (it's about stack, but it's the same reason for queue):

This restriction is the only reason for stack to exist at all. Note that any Front Insertion Sequence or Back Insertion Sequence can be used as a stack; in the case of vector, for example, the stack operations are the member functions back, push_back, and pop_back. The only reason to use the container adaptor stack instead is to make it clear that you are performing only stack operations, and no other operations.

So, if you really want to do this, you'll have to empty the stack (or queue):

std::stack<Whatever> s;
// ...
while(!s.empty())
{
    Whatever w = s.top();
    std::cout << w;
    s.pop();
}

Solution 3

ostream & operator<<(ostream & os, stack<double> my_stack) //function header
{
    while(!my_stack.empty()) //body
    {
        os << my_stack.top() << " ";
        my_stack.pop();
    }
    return os; // end of function
}


/*
using this simple overloaded operator function, you're able to print out all the components of a stack by doing a simple cout << your_stack_name;*/

Solution 4

Posting b/c I found this useful for debugging. Pop from original into a temp and then pop from temp back into original:

template <typename T>
void dump_stack(std::stack<T>& stack) {
  std::stack<T> temp;
  while (!stack.empty()) {
    T top = stack.top(); stack.pop();
    std::cout << top << " ";
    temp.push(top);
  }
  while (!temp.empty()) {
    T top = temp.top(); temp.pop();
    stack.push(top);
  }
}

Solution 5

It can be easily done using recursion you just need to know when to re-add the next element

For Stack

void print(stack<char> &s)
{
    if(s.empty())
    {
        cout << endl;
        return;
    }
    char x= s.top();
    s.pop();
    print(s);
    s.push(x);
    cout << x << " ";
 }

And this one is For Queue

void print(queue<char> &s,int num)
{
    if(!num)
    {
        cout << endl;
        return;
    }
    char x= s.front();
    s.pop();
    cout << x << " ";
    s.push(x);
    print(s,--num);
}

Good Luck

Share:
73,964

Related videos on Youtube

Qiang Li
Author by

Qiang Li

Updated on July 09, 2022

Comments

  • Qiang Li
    Qiang Li almost 2 years

    If I do not to want to create a new container in order to do so?

  • Qiang Li
    Qiang Li over 13 years
    regarding 1. of course, i do not want only to print out all elements when using the stack or queue.
  • Qiang Li
    Qiang Li over 13 years
    i don't want to empty it though, unless i made a copy before i do this. Still, i am wondering if there is a better solution. :)
  • Etienne de Martel
    Etienne de Martel over 13 years
    Then, use a vector (for a stack) or a deque (for a queue) instead. Stacks and queues are for very specific situations.
  • Khaled Alshaya
    Khaled Alshaya over 13 years
    There is no need to mess with the elements, you can get the underlying container with a simple hack. I used the code in my answer for debugging of course.
  • Khaled Alshaya
    Khaled Alshaya over 13 years
    @Qiang Li Please check my comment under the question it self where I refer to the original question where I found the solution.
  • Etienne de Martel
    Etienne de Martel over 13 years
    I know VC++'s implementation has a public field for the underlying container, but I'm not sure it's portable...
  • Khaled Alshaya
    Khaled Alshaya over 13 years
    Good note, but the code is actually standard and doesn't depend on a particular implementation. The standard says that the underlying container is protected! The way this code works is that it inherits std::stack(or std::queue) then it exposes the underlying container. Please, check the comment under the question itself to get an idea.
  • Steve Jessop
    Steve Jessop over 13 years
    This is true of the original STL as SGI developed it, but not true of the standard.
  • Etienne de Martel
    Etienne de Martel over 13 years
    Interesting, I didn't know that.
  • Ramakrishnan Kannan
    Ramakrishnan Kannan almost 8 years
    You will loose all the elements in the stack.
  • GingerPlusPlus
    GingerPlusPlus over 7 years
    @Ramakrishnan: no. He's taking the stack by copy, not by reference.
  • 425nesp
    425nesp over 2 years
    Note: Elements will be printed in reverse order in which they were pushed.
  • ramgorur
    ramgorur about 2 years
    Not at all, what if I want to see the content of a stack at every step inside a loop during the development?

Related