'How can I print out the contents of std::stack and return its size?

In c++ how can I print out the contents of my stack and return its size?

std::stack<int>  values;
values.push(1);
values.push(2);
values.push(3);

// How do I print the stack?


Solution 1:[1]

You could make a copy of the stack and pop items one-by-one to dump them:

#include <iostream>
#include <stack>
#include <string>

int main(int argc, const char *argv[])
{
    std::stack<int> stack;
    stack.push(1); 
    stack.push(3); 
    stack.push(7); 
    stack.push(19); 

    for (std::stack<int> dump = stack; !dump.empty(); dump.pop())
        std::cout << dump.top() << '\n';

    std::cout << "(" << stack.size() << " elements)\n";

    return 0;
}

Output

19
7
3
1
(4 elements)

See it live here: http://liveworkspace.org/code/9489ee305e1f55ca18c0e5b6fa9b546f

Solution 2:[2]

Both std::stack and std::queue are wrappers around a general container. That container is accessible as the protected member c. Using c you can gain efficient access to the elements; otherwise, you can just copy the stack or queue and destructively access the elements of the copy.

Example of using c:

#include <iostream>     // std::wcout, std::endl
#include <stack>        // std::stack
#include <stddef.h>     // ptrdiff_t
using namespace std;

typedef ptrdiff_t   Size;
typedef Size        Index;

template< class Elem >
Size nElements( stack< Elem > const& c )
{
    return c.size();
}

void display( stack<int> const& numbers )
{
    struct Hack
        : public stack<int>
    {
        static int item( Index const i, stack<int> const& numbers )
        {
            return (numbers.*&Hack::c)[i];
        }
    };

    wcout << numbers.size() << " numbers." << endl;
    for( Index i = 0;  i < nElements( numbers );  ++i )
    {
        wcout << "  " << Hack::item( i, numbers ) << endl;
    }
}

int main()
{
    stack<int>  numbers;
    for( int i = 1;  i <= 5;  ++i ) { numbers.push( 100*i ); }

    display( numbers );
}

Solution 3:[3]

The only way to print the elements of a std::stack without popping them, is to write an adapter that extends std::stack (here's an example). Otherwise, you should replace your stack with a std::deque.

Solution 4:[4]

A simple way of achieving this without using "special techniques" is through

Recursion

As there is no boundation that pop () member function of std::stack<> cannot be used, etc, we can make use of the following recursive algorithm.

Algorithm:

  1. Base case: If the stack is empty => return.
  2. Pop the top element and store it in a variable.
  3. Print the stored value.
  4. Recursively call for the rest of the elements of the stack.
  5. Push the element again on the stack.

Despite the pop operation, stack won't lose its elements as we are pushing them again in the same order after printing the rest of the stack.

Here is the code for the above algorithm:

void printStack (std::stack <int> &values) {
    
    if (values.empty ()) {
        return;
    }

    int topElement = values.top ();
    values.pop ();

    std::cout << topElement << std::endl;

    printStack (values);

    values.push (topElement);
}

Output of the above code:

3
2
1

This is going to print the elements from top to bottom fashion.

If you want the elements to be printed from bottom to top, just switch the recursive call and the std::cout statement.

void printStack (std::stack <int> &values) {
    
    if (values.empty ()) {
        return;
    }

    int topElement = values.top ();
    values.pop ();

    printStack (values);

    std::cout << topElement << std::endl;

    values.push (topElement);
}

Output:

1
2
3

And the size () member function of std::stack<> can be used to get the size of the stack.

std::cout << values.size () << std::endl;

Solution 5:[5]

Hm, a nearly 10 years old question. Anyway, here an additional answer.

First: The size of a stack is given by std::stack.size().

Then, in modern C++ the STL with algorithms is used more and more. So the following solution makes use of that. The precondition is that a stack uses contiguous memory. That is guaranteed at the moment.

Output is done via a one liner.

See the following example:

#include <vector>
#include <stack>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <sstream>

using Number = int;
using UnderlyingContainer = std::vector<Number>;
using Stack = std::stack< Number, UnderlyingContainer>;

std::istringstream testData("5 8 1 4 9 3");

int main()
{
    // Put the test data onto the stack
    Stack stack{ UnderlyingContainer {std::istream_iterator<Number>(testData),std::istream_iterator<Number>()} };

    // Print the test data
    if (not stack.empty())
        std::copy(&stack.top() + 1 - stack.size(), &stack.top() + 1, std::ostream_iterator<Number>(std::cout, "\n"));

    return 0;
}

This is completely valid and reliable code. Here a little bit more explanation.

We want to output the data, so we copy it to an ostream_iterator. The ostream_iterator takes a reference to a stream (Yes you can put also an open ofstream) and the deliminator. Maybe you want to use a " ".

The source for the copy are 2 iterators. And, yes, pointers are iterators. And, we make use of the guaranteed contiguous memory for a std::stack. So, we simply calculate 2 pointers and hand them over to std::copy.

And if you want to use explicit iterators. Here we go . .

#include <vector>
#include <stack>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <sstream>

using Number = int;
using UnderlyingContainer = std::vector<Number>;
using Stack = std::stack< Number, UnderlyingContainer>;

using StackIterator = const Number *;

std::istringstream testData("5 8 1 4 9 3");

int main()
{
    // Put the test data onto the stack
    Stack stack{ UnderlyingContainer {std::istream_iterator<Number>(testData),std::istream_iterator<Number>()} };

    // Print the test data
    // Get iterators
    StackIterator end = &stack.top() + 1;
    StackIterator begin = end - stack.size();

    if (not stack.empty())
        std::copy(begin, end, std::ostream_iterator<Number>(std::cout, "\n"));

    return 0;
}

So you can create iterators for a stack. But, caveat:

The std::stack intentionally hides its elements under the hood. So, if you write-access the data, I would see it as a design fault. Read-access through const pointers/iterators is for me OK. But maybe you should better use a std::vector . . .

Solution 6:[6]

For coding exercises I use this stack implementation:

#include <vector>

using std::vector;

template<class T>
class my_stack : public vector<T> {
    public:
    using vector<T>::vector; ///Takes all the constructors
    void push(T value) {
        vector<T>::push_back(value);
    }
    T pop() {
        T ret_val = vector<T>::back();
        vector<T>::pop_back();
        return ret_val;
    }
    
};

Advantages:

  • Can be easily printed
  • Can be brace initialised with the desired content
  • Bonus feature: pop() returns the value popped

Caveat:
You have to be careful not to use "forbidden" methods like front(). To prevent that, you can inherit vector as protected, then it becomes relevant to specify your printing function:

#include <iostream>
#include <vector>

using std::vector;

template<class T>
class my_stack : protected vector<T> {
    public:
    using vector<T>::vector; ///Takes all the constructors
    using vector<T>::size;
    void push(T value) {
        vector<T>::push_back(value);
    }
    T pop() {
        T ret_val = vector<T>::back();
        vector<T>::pop_back();
        return ret_val;
    }
    friend std::ostream& operator<< <> (std::ostream&, const my_stack<T>& vec);

};

template<typename T>
std::ostream& operator<<(std::ostream& os, const my_stack<T>& in) {
    for (auto& el : in) {
        os << el << ' ';
    }
    return os;
}

Solution 7:[7]

http://www.cplusplus.com/reference/stl/stack/ for the size it's easy use :

cout << mystack.size();

For the rest i didn't see anything about in the doc but you should print the content of your stack when you push it, or have a list with it to keep a record of the element just in order to print it, don't forget to delete it when you're done testing

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 Community
Solution 4
Solution 5 Armin Montigny
Solution 6 Antonio
Solution 7 Morendo