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?
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?
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)
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 );
}
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
.
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:
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;
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 . . .
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:
pop()
returns the value poppedCaveat:
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;
}
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