Output of a vector

In a book, I've got a program to print a vector using iterator. Here's it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <vector>
#include <string>
using namespace std;
using std::vector;
using std::string;
int main()
{
    vector<string> text;
    int iter;
    for (vector<string>::const_iterator iter = text.begin();
         iter != text.end(); ++iter)
    cout << *iter << endl;
    system ("pause");
    return 0;
}



Though the code is compiled successfully, there's no output. So, what should the input exactly? What more should I add?

Moreover, I want to know how to print output of a vector. Why doesn't cout << vector<string>example << endl; fail to print out vectors? Is there any other method?
Last edited on
The string header isn't declared

#include<string>

The scope of cout and endl needs to be mentioned

std::cout << *iter << std::endl

cout << vector<string>example << endl;

What you are suggesting to do here is like:

cout << int x << endl;

You can't cout a type, but even if it's...

1
2
3
vector<string> example;

cout << example << endl;


...it is still not possible. I don't know the nitty gritty of it, but basically vector is a class that does not support the << operator to print all its elements in such a direct fashion.

To print the vector contents, you can either use this way here, which is using iterators, use subscripts [] like arrays, or call the at member.

1
2
3
4
5
6
7
vector<int> example {1,2,3,4,5,6, 7};

for (int x = 0; x != example.size(); ++x)
{
     cout << example[x] << "- subscripting" << endl;
     cout << example.at(x) << "- calling at member" << endl;
}


Edit: Despite that, using iterators is generally better when working with containers like vector (ie for printing, modifying the elements, etc.)
Last edited on
Why doesn't cout << vector<string>example << endl; fail to print out vectors?

Because there is standard insertion operator defined for vector. But you can provide one.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <vector>
#include <string>
using std::string;
using std::vector;
using std::ostream;
using std::cout;
using std::endl;

template <typename TElem>
ostream& operator<<(ostream& os, const vector<TElem>& vec) {
    typedef vector<TElem>::const_iterator iter_t;
    const iter_t iter_begin = vec.begin();
    const iter_t iter_end   = vec.end();
    os << "[";
    for (iter_t iter = iter_begin; iter != iter_end; ++iter) {
        cout << ((iter != iter_begin) ? "," : "") << *iter;
    }
    os << "]";
    return os;
}

int main() {
    vector<string> text;
    text.push_back("one");
    text.push_back("two");
    text.push_back("three");

    cout << "text = " << text << endl;

    system ("pause");
    return 0;
}


Output:
text = [one,two,three]
Press any key to continue . . .


Is there any other method?

You could use an ostream_iterator with the copy algorithm?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using std::string;
using std::vector;
using std::copy;
using std::cout;
using std::endl;

int main() {
    vector<string> text;
    text.push_back("one");
    text.push_back("two");
    text.push_back("three");

    cout << "text = ";

    std::ostream_iterator<string> out_it(std::cout,", ");
    std::copy(text.begin(), text.end(), out_it);
    
    cout << endl;

    system ("pause");
    return 0;
}


Output:
text = one, two, three,
Press any key to continue . . .


See: ostream_iterator
http://www.cplusplus.com/reference/iterator/ostream_iterator/

But you could just factor out the vector display code into a helper function so can use that each time you want to display your vector?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <vector>
#include <string>
using namespace std;
using std::vector;
using std::string;

void write_vec(const vector<string>& vec) {
    for (vector<string>::const_iterator iter = vec.begin();
        iter != vec.end(); ++iter) {
        cout << *iter << ", ";
    }
}

int main() {
    vector<string> text;

    cout << "empty vector : ";
    write_vec(text);
    cout << endl;

    text.push_back("one");
    text.push_back("two");
    text.push_back("three");

    cout << "full vector : ";
    write_vec(text);
    cout << endl;

    text.push_back("four");

    cout << "fuller vector : ";
    write_vec(text);
    cout << endl;

    system ("pause");
    return 0;
}


Andy
Last edited on
technovator wrote:
there's no output
That's because there's nothing int he vector to output.
to append items to the vector you use the method vector<T>::push_back.
example:
1
2
3
4
5
6
vector<std::string> text;
text.push_back("Some text here.");
text.push_back("Some more text.");
text.push_back("Third bit of text.");

//text now contains 3 strings.  


technovator wrote:
Why doesn't cout << vector<string>example << endl; fail to print out vectors?
The vector container doesn't have a default overload for ostream &operator<< because there are many different ways that you might want to output a vector. (i.e., do you want commas in between data? do you want spaces separating them? do you want new lines? or none of the above?)
There's no way for the library developers to know how you want to output the data in your vector, so they left the task up to the user to do.

There are many different ways to output stl containers. With C++11, range-based for loops make it a bit easier:
1
2
3
std::vector<string> text; //assume text has been filled with some data
for(auto &i: text)
    std::cout << i << endl; //output one element per line 

which is the same thing as
1
2
3
4
std::vector<string> text; 

for(std::vector<string>::iterator it = text.begin(); it != text.end(); ++it)
    std::cout << *it << endl;


You can use std::copy and ostream iterators
1
2
3
4
5
#include <iterator>
std::vector<string> text;

//output each element separated by a space
std::copy(text.begin(), text.end(), std::ostream_iterator<string>(cout, " "));



And if you really want to you can overload << to output your vector how you want it.
1
2
3
4
5
6
7
std::ostream &operator<<(std::ostream &os, std::vector<string> &v)
{
    for(auto &i: v)
        os << v << std::endl;

    return os;
}


EDIT:
beat by andy
Last edited on
@Olysold

When you say

using iterators is generally better when working with containers like vector

What do you mean by better?

The performance of index-based and iterator-based access is roughly the same for the optimized build. So there is not a "better" in that sense.

You do need to use iterators if you want to work with the standard algorithms, but there are cases where index based operations can be tidier.

1
2
3
4
5
    const size_t count = text.size();

    for (size_t index = 0; index < count; ++index) {
        cout << index << " = " << text[index] << endl;
    }


versus

1
2
3
4
5
6
7
    typedef vector<string>::const_iterator iter_t;
    const iter_t iter_begin = text.begin();
    const iter_t iter_end   = text.end();

    for (iter_t iter = iter_begin; iter != iter_end; ++iter) {
        cout << distance(iter_begin, iter) << " = " << *iter << endl;
    }


I have to admit that I tend to use index based access for basic situations, and iterators for more involved, algorthmic purposes.

Note also that when checked iterators are used, they are slower than index-based access, so you might get slower debug build if you use iterators.

Andy
Last edited on
@Andy

Nah I wasn't referring to performance-wise, should have been clear about that though. The question did pop up in my head, did a little searching and as you've mentioned its' negligible.

I mean as in it integrates better with the environment of working with other containers/algorithm functions as they all have iterator support but not subscripts.

But yea if it's a basic situation (just working with vectors) there isn't a difference I suppose. Subscripts are easier on the eyes even imo.
@andy you can also just add a count variable when using iterators but yeah I think if you want to know the count it's better to use a index based =p
1
2
3
4
5
6
auto count( 0u );
for( const auto &it : vec )
{
    std::cout << it << " = " << count <<  " position" << std::endl;
    ++count;
}
Topic archived. No new replies allowed.