5

How can I pretty-print a std::vector? For example, if I construct a std::vector<int>(6, 1), what can I run it through to get output like {1 1 1 1 1 1} in C++? It needs to be generic as the size and value might change, so std::vector<int>(4, 0) would be {0 0 0 0}.

Michael Mrozek
  • 169,610
  • 28
  • 168
  • 175
dharag
  • 299
  • 1
  • 8
  • 17

1 Answers1

14
#include <vector>
#include <algorithm>
#include <iterator>

template<typename T>
std::ostream & operator<<(std::ostream & os, std::vector<T> vec)
{
    os<<"{ ";
    std::copy(vec.begin(), vec.end(), std::ostream_iterator<T>(os, " "));
    os<<"}";
    return os;
}

then you can output your vectors with the normal operator<< syntax:

std::cout<<yourVector;

you can see this in action here.

But for more flexible solutions have a look at the question linked above.


Edit: if you don't want the two spaces (at the beginning and at the end):

template<typename T>
std::ostream & operator<<(std::ostream & os, std::vector<T> vec)
{
    os<<"{";
    if(vec.size()!=0)
    {
        std::copy(vec.begin(), vec.end()-1, std::ostream_iterator<T>(os, " "));
        os<<vec.back();
    }
    os<<"}";
    return os;
}
hsandt
  • 709
  • 7
  • 12
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • Note that this will not produce the output the OP requested, because it will have a trailing separator: `{0 0 0 0 }` (if that matters). – Björn Pollex Mar 15 '13 at 14:53
  • Probably a typo/missed by C&P'ing, but if you template your operator for arbitrary `T`, you don't want `ostream_iterator`. – us2012 Mar 15 '13 at 14:54
  • @us2012: correct, fixed. – Matteo Italia Mar 15 '13 at 14:55
  • 1
    @BjörnPollex: you are right, for some reason I always think that `ostream_iterator` takes care of that. Well, I'll just add a space at the start to make it symmetrical. :) – Matteo Italia Mar 15 '13 at 14:55
  • 3
    @MatteoItalia: It's the reason why I only use this with whitespace or newline as separator, because it is practically useless for anything else. On the other hand, you add a check if the vector is not empty, and then just copy until `--vec.end()` and print the last item in an extra step. – Björn Pollex Mar 15 '13 at 14:57
  • I have a problem that sometimes the value std::vector(4,0) is stored in a string, for some reason. like str = "std::vector(4,0)" and is displayed in the database as it is. But I would like to display it as {0 0 0 0} Is it possible to do some type conversion for these cases ?? – dharag Mar 15 '13 at 21:10
  • @user2029504: you can't evaluate that kind of expression at runtime in C++; if you really need such a thing, you could write some kind of ad-hoc parser, but the best solution is just to store the vector in some fixed, easily parsable format (like the one we are talking about here). – Matteo Italia Mar 16 '13 at 01:44
  • #include using namespace std; int main() { string str = "std::vector(6,0)" ; unsigned found = str.find('('); char c = str[found+1]; int i = c - '0'; char ch = str[found+3]; int j = ch - '0'; str = "{ "; for(int k = 0; k < i ; k++) { str = str + ch + " " ; } str = str + " }"; cout << str << endl; return 0; } – dharag Mar 18 '13 at 14:55
  • This does the work but does not look very nice. Also, how do I post it here so that its more readable. Sorry – dharag Mar 18 '13 at 14:56
  • @user2029504: create another question for this new problem. – Matteo Italia Mar 18 '13 at 15:03
  • Works with back() instead of last(). I've already suggested the edit. – hsandt Oct 18 '17 at 16:51
  • @hsandt: thank you, approved! – Matteo Italia Oct 18 '17 at 17:37