10

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?
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
John
  • 1,556
  • 4
  • 26
  • 42
  • 1
    What kind of formatting do you want? There's no way to have a format that pleases everyone. – chris Sep 27 '12 at 23:26
  • What do you mean by `stack`? Do you mean `std::stack<>` or do you mean the `call stack` or some other stack. A bit more specific in the details please. – Martin York Sep 27 '12 at 23:31
  • say if i have a stack of integers a,and i push the ints by a.push(1) a.push(2) a.push(3) how could i print out 1,2,3? – John Sep 27 '12 at 23:31

7 Answers7

21

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

sehe
  • 374,641
  • 47
  • 450
  • 633
  • won't it empty his stack ? is there a solution to do it with out poping ? – Morendo Sep 27 '12 at 23:36
  • 4
    It won't because I copy it first (into `dump`). The solution without pop-ing is the solution without a stack. If you need a random-access (general purpose) container, don't use the stack container adaptor. – sehe Sep 27 '12 at 23:38
  • Not really, that is just shorthand for the type of `stack`. I will edit to spell it out in C++03 style :) – sehe Sep 27 '12 at 23:47
6

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 );
}
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
4

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.

Community
  • 1
  • 1
jweyrich
  • 31,198
  • 5
  • 66
  • 97
1

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;
0

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 . . .

A M
  • 14,694
  • 5
  • 19
  • 44
0

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;
}
Antonio
  • 19,451
  • 13
  • 99
  • 197
-1

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

Morendo
  • 752
  • 1
  • 4
  • 23