I want to print out the contents of a vector in C++, here is what I have:
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
#include <sstream>
#include <cstdio>
using namespace std;
int main()
{
std::ifstream file("maze.txt");
if (file) {
std::vector<char> vec(std::istreambuf_iterator<char>(file), (std:;
}
}
Purely to answer your question you, can use an iterator:
std::vector<char> path; // ... for (std::vector<char>::const_iterator i = path.begin(); i != path.end(); ++i) std::cout << *i << ' ';
If you want to modify the vector's contents in the for loop, then use
iterator rather than
const_iterator.
But there's lots more that can be said about this. If you just want an answer you can use, then you can stop here; otherwise, read on.
This is not another solution, but a supplement to the above
iterator solution. If you are using the C++11 standard (or later), then you can use the
auto keyword to help the readability:
for (auto i = path.begin(); i != path.end(); ++i) std::cout << *i << ' ';
But the type of
i will be non-const (i.e., the compiler will use
std::vector<char>::iterator as the type of
i).
In this case, you might as well just use a
typedef (not restricted to C++11, and very useful to use anyway):
typedef std::vector<char> Path; Path path; // ... for (Path::const_iterator i = path.begin(); i != path.end(); ++i) std::cout << *i << ' ';
You can, of course, use a integer type to record your position in the
for loop:.
// Path typedef'd to std::vector<char> for( Path::size_type i=0; i<path.size(); ++i) std::cout << path[i] << ' ';
Why not just use this over the
iterator solution? For simple cases you might as well, but the point is that the
iterator class is an object designed to do this job for more complicated objects where this solution is not going to be ideal.
See Jefffrey's solution. In C++11 (and later) you can use the new range-based
for loop, which looks like this:
for (auto i: path) std::cout << i << ' ';
Since
path is a vector of items (explicitly
std::vector<char>), the object
i is of type of the item of the vector (i.e., explicitly, it is of type
char). The object
i has a value that is a copy of the actual item in the
path object. Thus, all changes to
i in the loop are not preserved in
path itself. Additionally, if you would like to enforce the fact that you don't want to be able to change the copied value of
i in the loop, you can force the type of
i to be
const char like this:
for (const auto i: path) std::cout << i << ' ';
If you would like to modify the items in
path, you can use a reference:
for (auto& i: path) std::cout << i << ' ';
and even if you don't want to modify
path, if the copying of objects is expensive you should use a const reference instead of copying by value:
for (const auto& i: path) std::cout << i << ' ';
See Joshua's answer. You can use the STL algorithm
std::copy to copy the vector contents onto the output stream. This is an elegant solution if you are comfortable with it (and besides, it is very useful, not just in this case of printing the contents of a vector).
See Max's solution. Using
std::for_each is overkill for this simple scenario, but it is a very useful solution if you wanted to do more than just printing to screen: using
std::for_each allows you to do any (sensible) operation on the vector contents.
See Chris's answer, this is more a complement to the other answers since you will still need to implement one of the solutions above in the overloading. In his example he used a counter in a
for loop. For example, this is how you could quickly use Joshua's solution:
template <typename T> std::ostream& operator<< (std::ostream& out, const std::vector<T>& v) { if ( !v.empty() ) { out << '['; std::copy (v.begin(), v.end(), std::ostream_iterator<T>(out, ", ")); out << "\b\b]"; } return out; }
Usage of any of the other solutions should be straightforward.
Any of the solutions presented here will work. It's up to you and the code on which one is the "best". Anything more detailed than this is probably best left for another question where the pros/cons can be properly evaluated; but as always user preference will always play a part: none of the solutions presented are wrong, but some will look nicer to each individual coder.
This is an expanded solution of an earlier one I posted. Since that post kept getting attention, I decided to expand on it and refer to the other excellent solutions that were posted here. My original post had a remark that mentioned that if you were intending on modifying your vector inside a
for loop then there are two methods provided by
std::vector to access elements:
std::vector::operator[] which does not do bounds checking, and
std::vector::at which does perform bounds checking. In other words,
at will throw if you try to access an element outside the vector and
operator[] wouldn't. I only added this comment, originally, for the sake of mentioning something that it might be useful to know of if anyone already didn't. And I see no difference now. Hence this addendum.