如何输出矢量的内容?

时间:2022-03-01 20:37:54

I want to print out the contents of a vector in C++, here is what I have:

我想用c++打印出向量的内容,这是我的

#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
#include <sstream>
#include <cstdio>
using namespace std;

int main()
{
    ifstream file("maze.txt");
    if (file) {
        vector<char> vec(istreambuf_iterator<char>(file), (istreambuf_iterator<char>()));
        vector<char> path;
        int x = 17;
        char entrance = vec.at(16);
        char firstsquare = vec.at(x);
        if (entrance == 'S') { 
            path.push_back(entrance); 
        }
        for (x = 17; isalpha(firstsquare); x++) {
            path.push_back(firstsquare);
        }
        for (int i = 0; i < path.size(); i++) {
            cout << path[i] << " ";
        }
        cout << endl;
        return 0;
    }
}

How do I print the contents of the vector to the screen?

如何将矢量的内容打印到屏幕上?

13 个解决方案

#1


262  

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.

如果希望在for循环中修改向量的内容,那么使用迭代器而不是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.

但关于这一点还有很多可以说的。如果你只想要一个你可以使用的答案,那么你可以停在这里;否则,请继续阅读。

auto (C++11)/typedef

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:

这不是另一个解决方案,而是上述迭代器解决方案的补充。如果您正在使用c++ 11标准(或更高版本),那么您可以使用auto关键字来帮助提高可读性:

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

但是i的类型是不固定的。,编译器将使用std::vector ::iterator作为i的类型)。

In this case, you might as well just use a typedef (not restricted to C++11, and very useful to use anyway):

在这种情况下,您也可以使用类型定义(不限于c++ 11,无论如何使用都非常有用):

typedef std::vector<char> Path;
Path path;
// ...
for (Path::const_iterator i = path.begin(); i != path.end(); ++i)
    std::cout << *i << ' ';

counter

You can, of course, use a integer type to record your position in the for loop:

当然,您可以使用整数类型来记录for循环中的位置:

for(int i=0; i<path.size(); ++i)
  std::cout << path[i] << ' ';

If you are going to do this, it's better to use the container's member types, if they are available and appropriate. std::vector has a member type called size_type for this job: it is the type returned by the size method.

如果您打算这样做,最好使用容器的成员类型,如果它们是可用的和适当的。vector有一个名为size_type的成员类型,它是size方法返回的类型。

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

为什么不直接使用迭代器解决方案呢?对于简单的情况,您也可以这样做,但重点是iterator类是一个对象,它设计用于处理更复杂的对象,而这个解决方案并不理想。

range-based for loop (C++11)

See Jefffrey's solution. In C++11 (and later) you can use the new range-based for loop, which looks like this:

看到Jefffrey的解决方案。在c++ 11(稍后)中,您可以使用新的基于范围的for循环,它是这样的:

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:

由于路径是项的向量(显式的std: vector ),所以对象i是向量项的类型(即。,它是char类型)。对象i有一个值,该值是path对象中实际项目的副本。因此,循环中对i的所有更改都不会保留在路径本身中。此外,如果您想强制执行这样一个事实,即您不想更改循环中复制的i的值,您可以强制i的类型为const char,如下所示:

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:

即使你不想修改路径,如果复制对象的费用很高,你应该使用const引用而不是按值复制:

for (const auto& i: path)
  std::cout << i << ' ';

std::copy

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

看到约书亚的答案。可以使用STL算法std::copy将矢量内容复制到输出流中。这是一个优雅的解决方案,如果您对它感到满意(而且,它是非常有用的,不仅仅是在这种情况下打印一个矢量的内容)。

std::for_each

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.

看到麦克斯的解决方案。对于这个简单的场景,使用std::for_each是多余的,但是如果您想要做的不仅仅是打印到屏幕:使用std::for_each允许您对vector内容执行任何(合理的)操作,那么它是一个非常有用的解决方案。

overload ostream::operator<<

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:

参见Chris的答案,这是对其他答案的补充,因为在重载过程中仍然需要实现上面的一个解决方案。在他的例子中,他在for循环中使用了计数器。例如,这就是你如何快速使用Joshua的解决方案:

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.

其他任何解决方案的使用都应该简单明了。

conclusion

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.

这里提供的任何解决方案都将有效。这取决于你和密码,哪个是最好的。任何比这更详细的内容可能最好留给下一个问题,在这个问题中,正反两方面可以得到适当的评估;但一如既往,用户偏好总是起着一定的作用:所提供的解决方案没有一个是错误的,但是对于每个单独的程序员来说,有些解决方案看起来会更好。

addendum

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.

这是我之前发布的一个扩展解决方案。由于这篇文章一直受到关注,我决定对它进行扩展,并参考这里发布的其他优秀解决方案。我最初的帖子中提到,如果您打算在for循环中修改向量,那么std提供了两种方法:::::vector访问元素:std::vector: operator[],它不做边界检查;换句话说,如果您试图访问向量之外的元素,则会随意抛出,而操作符[]则不会。我只是添加了这条评论,最初,是为了提及一些可能有用的信息,如果有人没有的话。现在我看不出有什么不同。因此这个附录。

#2


177  

A much easier way to do this is with the standard copy algorithm:

一种更简单的方法是使用标准的复制算法:

#include <iostream>
#include <algorithm> // for copy
#include <iterator> // for ostream_iterator
#include <vector>

int main() {
    /* Set up vector to hold chars a-z */
    std::vector<char> path;
    for (int ch = 'a'; ch <= 'z'; ++ch)
        path.push_back(ch);

    /* Print path vector to console */
    std::copy(path.begin(), path.end(), std::ostream_iterator<char>(std::cout, " "));

    return 0;
}

The ostream_iterator is what's called an iterator adaptor. It is templatized over the type to print out to the stream (in this case, char). cout (aka console output) is the stream we want to write to, and the space character (" ") is what we want printed between each element stored in the vector.

ostream_iterator是所谓的迭代器适配器。它在打印到流(在本例中为char)的类型上进行了模板化。cout(也称为控制台输出)是我们想要写入的流,而空格字符(“”)是我们想要在存储在向量中的每个元素之间打印的。

This standard algorithm is powerful and so are many others. The power and flexibility the standard library gives you are what make it so great. Just imagine: you can print a vector to the console with just one line of code. You don't have to deal with special cases with the separator character. You don't need to worry about for-loops. The standard library does it all for you.

这个标准算法非常强大,其他很多算法也是如此。标准库赋予您的力量和灵活性使它如此伟大。想象一下:只需一行代码就可以将向量打印到控制台。您不必处理带有分隔符的特殊情况。你不需要担心for循环。标准库为您做了所有这些。

#3


58  

In C++11 you can now use a range-based for loop:

在c++ 11中,您现在可以使用基于范围的for循环:

for (auto const& c : path)
    std::cout << c << ' ';

#4


32  

I think the best way to do this is to just overload operator<< by adding this function to your program:

我认为最好的方法就是重载操作符<< <通过将这个函数添加到你的程序中:< p>

#include <vector>
using std::vector;
#include <iostream>
using std::ostream;

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& v) {
    out << "{";
    size_t last = v.size() - 1;
    for(size_t i = 0; i < v.size(); ++i) {
        out << v[i];
        if (i != last) 
            out << ", ";
    }
    out << "}";
    return out;
}

Then you can use the << operator on any possible vector, assuming its elements also have ostream& operator<< defined:

然后可以在任何可能的向量上使用< <运算符,假设它的元素也有ostream&operator <已定义:< p>

vector<string>  s = {"first", "second", "third"};
vector<bool>    b = {true, false, true, false, false};
vector<int>     i = {1, 2, 3, 4};
cout << s << endl;
cout << b << endl;
cout << i << endl;

Outputs:

输出:

{first, second, third}
{1, 0, 1, 0, 0}
{1, 2, 3, 4}

#5


13  

How about for_each + lambda expression:

for_each + lambda表达式:

#include <vector>
#include <algorithm>
...
std::vector<char> vec;
...
std::for_each(
              vec.cbegin(),
              vec.cend(),
              [] (const char c) {std::cout << c << " ";} 
              );
...

Of course, a range-based for is the most elegant solution for this concrete task, but this one gives many other possibilities as well.

当然,基于范围的for是这个具体任务最优雅的解决方案,但是这个解决方案也提供了许多其他的可能性。

Explanation

解释

The for_each algorithm takes an input range and a callable object, calling this object on every element of the range. An input range is defined by two iterators. A callable object can be a function, a pointer to function, an object of a class which overloads () operator or as in this case, a lambda expression. The parameter for this expression matches the type of the elements from vector.

for_each算法接受一个输入范围和一个可调用对象,在范围的每个元素上调用这个对象。输入范围由两个迭代器定义。可调用对象可以是函数、指向函数的指针、重载()运算符的类的对象,也可以是lambda表达式。这个表达式的参数与vector中的元素的类型匹配。

The beauty of this implementation is the power you get from lambda expressions - you can use this approach for a lot more things than just printing the vector.

这种实现的美妙之处在于您可以从lambda表达式中获得强大的功能——您可以使用这种方法做更多的事情,而不仅仅是打印向量。

#6


7  

The problem is probably in the previous loop: (x = 17; isalpha(firstsquare); x++). This loop will run not at all (if firstsquare is non-alpha) or will run forever (if it is alpha). The reason is that firstsquare doesn't change as x is incremented.

问题可能在前面的循环中:(x = 17;isalpha(firstsquare);x + +)。这个循环将不会运行(如果firstsquare是非alpha),或者将永远运行(如果它是alpha)。原因是firstsquare不会随着x的增加而改变。

#7


5  

Just copy the container to the console.

只需将容器复制到控制台。

std::vector<int> v{1,2,3,4};
std::copy(v.begin(),v.end(),std::ostream_iterator<int>(std::cout, " " ));

Should output :

应该输出:

1 2 3 4

#8


3  

In C++11, a range-based for loop might be a good solution:

在c++ 11中,基于范围的for循环可能是一个很好的解决方案:

vector<char> items = {'a','b','c'};
for (char n : items)
    cout << n << ' ';

Output: a b c

输出:a b c

#9


2  

I see two problems. As pointed out in for (x = 17; isalpha(firstsquare); x++) there's either an infinite loop or never executed at all, and also in if (entrance == 'S') if the entrance character is different than 'S' then nothing in pushed to the path vector, making it empty and thus printing nothing on screen. You can test the latter checking for path.empty() or printing path.size().

我看到两个问题。如式(x = 17)所示;isalpha(firstsquare);x++)要么是无限循环,要么根本就没有执行,如果入口字符与“S”不同,那么就没有什么东西被推到路径矢量上,使它为空,从而在屏幕上不打印任何东西。您可以测试后一个检查路径.empty()或打印路径.size()。

Either way, wouldn't it be better to use a string instead of a vector? You can access the string contents like an array as well, seek characters, extract substrings and print the string easily (without a loop).

不管怎样,使用字符串而不是向量是不是更好?您还可以像访问数组一样访问字符串内容、查找字符、提取子字符串并轻松打印字符串(无需循环)。

Doing it all with strings might be the way to have it written in a less convoluted way and easier to spot the problem.

使用字符串来完成所有这些操作,可能是一种让它以一种不那么复杂、更容易发现问题的方法。

#10


2  

overload operator<<:

重载操作符< <:

template<typename OutStream, typename T>
OutStream& operator<< (OutStream& out, const vector<T>& v)
{
    for (auto const& tmp : v)
        out << tmp << " ";
    out << endl;
    return out;
}

Usage:

用法:

vector <int> test {1,2,3};
wcout << test; // or any output stream

#11


1  

This answer is based on the answer from Zorawar, but i couldn't leave a comment there.

这个答案是基于Zorawar的回答,但是我不能在那里留下任何评论。

You can make the auto (C++11)/typedef version const by using cbegin and cend instead

您可以使用cbegin和来代替auto (c++ 11)/typedef版本const

for (auto i = path.cbegin(); i != path.cend(); ++i)
    std::cout << *i << ' ';

#12


1  

Using std::copy but without extra trailing separator

An alternative/modified approach using std::copy (as originally used in @JoshuaKravtiz answer) but without including an additional trailing separator after the last element:

使用std::copy(最初用于@JoshuaKravtiz answer)替代/修改的方法,但是在最后一个元素之后不包含附加的尾随分隔符:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

template <typename T>
void print_contents(const std::vector<T>& v, const char * const separator = " ")
{
    if(!v.empty())
    {
        std::copy(v.begin(),
                  --v.end(),
                  std::ostream_iterator<T>(std::cout, separator));
        std::cout << v.back() << "\n";
    }
}

// example usage
int main() {
    std::vector<int> v{1, 2, 3, 4};
    print_contents(v);      // '1 2 3 4'
    print_contents(v, ":"); // '1:2:3:4'
    v = {};
    print_contents(v);      // ... no std::cout
    v = {1};
    print_contents(v);      // '1'
    return 0;
}

Example usage applied to container of a custom POD type:

应用于自定义POD类型容器的示例用法:

// includes and 'print_contents(...)' as above ...

class Foo
{
    int i;
    friend std::ostream& operator<<(std::ostream& out, const Foo& obj);
public:
    Foo(const int i) : i(i) {}
};

std::ostream& operator<<(std::ostream& out, const Foo& obj)
{
    return out << "foo_" << obj.i; 
}

int main() {
    std::vector<Foo> v{1, 2, 3, 4};
    print_contents(v);      // 'foo_1 foo_2 foo_3 foo_4'
    print_contents(v, ":"); // 'foo_1:foo_2:foo_3:foo_4'
    v = {};
    print_contents(v);      // ... no std::cout
    v = {1};
    print_contents(v);      // 'foo_1'
    return 0;
}

#13


0  

In C++11``

在c++中11 ' '

for (auto i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';

for(int i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';

#1


262  

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.

如果希望在for循环中修改向量的内容,那么使用迭代器而不是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.

但关于这一点还有很多可以说的。如果你只想要一个你可以使用的答案,那么你可以停在这里;否则,请继续阅读。

auto (C++11)/typedef

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:

这不是另一个解决方案,而是上述迭代器解决方案的补充。如果您正在使用c++ 11标准(或更高版本),那么您可以使用auto关键字来帮助提高可读性:

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

但是i的类型是不固定的。,编译器将使用std::vector ::iterator作为i的类型)。

In this case, you might as well just use a typedef (not restricted to C++11, and very useful to use anyway):

在这种情况下,您也可以使用类型定义(不限于c++ 11,无论如何使用都非常有用):

typedef std::vector<char> Path;
Path path;
// ...
for (Path::const_iterator i = path.begin(); i != path.end(); ++i)
    std::cout << *i << ' ';

counter

You can, of course, use a integer type to record your position in the for loop:

当然,您可以使用整数类型来记录for循环中的位置:

for(int i=0; i<path.size(); ++i)
  std::cout << path[i] << ' ';

If you are going to do this, it's better to use the container's member types, if they are available and appropriate. std::vector has a member type called size_type for this job: it is the type returned by the size method.

如果您打算这样做,最好使用容器的成员类型,如果它们是可用的和适当的。vector有一个名为size_type的成员类型,它是size方法返回的类型。

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

为什么不直接使用迭代器解决方案呢?对于简单的情况,您也可以这样做,但重点是iterator类是一个对象,它设计用于处理更复杂的对象,而这个解决方案并不理想。

range-based for loop (C++11)

See Jefffrey's solution. In C++11 (and later) you can use the new range-based for loop, which looks like this:

看到Jefffrey的解决方案。在c++ 11(稍后)中,您可以使用新的基于范围的for循环,它是这样的:

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:

由于路径是项的向量(显式的std: vector ),所以对象i是向量项的类型(即。,它是char类型)。对象i有一个值,该值是path对象中实际项目的副本。因此,循环中对i的所有更改都不会保留在路径本身中。此外,如果您想强制执行这样一个事实,即您不想更改循环中复制的i的值,您可以强制i的类型为const char,如下所示:

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:

即使你不想修改路径,如果复制对象的费用很高,你应该使用const引用而不是按值复制:

for (const auto& i: path)
  std::cout << i << ' ';

std::copy

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

看到约书亚的答案。可以使用STL算法std::copy将矢量内容复制到输出流中。这是一个优雅的解决方案,如果您对它感到满意(而且,它是非常有用的,不仅仅是在这种情况下打印一个矢量的内容)。

std::for_each

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.

看到麦克斯的解决方案。对于这个简单的场景,使用std::for_each是多余的,但是如果您想要做的不仅仅是打印到屏幕:使用std::for_each允许您对vector内容执行任何(合理的)操作,那么它是一个非常有用的解决方案。

overload ostream::operator<<

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:

参见Chris的答案,这是对其他答案的补充,因为在重载过程中仍然需要实现上面的一个解决方案。在他的例子中,他在for循环中使用了计数器。例如,这就是你如何快速使用Joshua的解决方案:

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.

其他任何解决方案的使用都应该简单明了。

conclusion

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.

这里提供的任何解决方案都将有效。这取决于你和密码,哪个是最好的。任何比这更详细的内容可能最好留给下一个问题,在这个问题中,正反两方面可以得到适当的评估;但一如既往,用户偏好总是起着一定的作用:所提供的解决方案没有一个是错误的,但是对于每个单独的程序员来说,有些解决方案看起来会更好。

addendum

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.

这是我之前发布的一个扩展解决方案。由于这篇文章一直受到关注,我决定对它进行扩展,并参考这里发布的其他优秀解决方案。我最初的帖子中提到,如果您打算在for循环中修改向量,那么std提供了两种方法:::::vector访问元素:std::vector: operator[],它不做边界检查;换句话说,如果您试图访问向量之外的元素,则会随意抛出,而操作符[]则不会。我只是添加了这条评论,最初,是为了提及一些可能有用的信息,如果有人没有的话。现在我看不出有什么不同。因此这个附录。

#2


177  

A much easier way to do this is with the standard copy algorithm:

一种更简单的方法是使用标准的复制算法:

#include <iostream>
#include <algorithm> // for copy
#include <iterator> // for ostream_iterator
#include <vector>

int main() {
    /* Set up vector to hold chars a-z */
    std::vector<char> path;
    for (int ch = 'a'; ch <= 'z'; ++ch)
        path.push_back(ch);

    /* Print path vector to console */
    std::copy(path.begin(), path.end(), std::ostream_iterator<char>(std::cout, " "));

    return 0;
}

The ostream_iterator is what's called an iterator adaptor. It is templatized over the type to print out to the stream (in this case, char). cout (aka console output) is the stream we want to write to, and the space character (" ") is what we want printed between each element stored in the vector.

ostream_iterator是所谓的迭代器适配器。它在打印到流(在本例中为char)的类型上进行了模板化。cout(也称为控制台输出)是我们想要写入的流,而空格字符(“”)是我们想要在存储在向量中的每个元素之间打印的。

This standard algorithm is powerful and so are many others. The power and flexibility the standard library gives you are what make it so great. Just imagine: you can print a vector to the console with just one line of code. You don't have to deal with special cases with the separator character. You don't need to worry about for-loops. The standard library does it all for you.

这个标准算法非常强大,其他很多算法也是如此。标准库赋予您的力量和灵活性使它如此伟大。想象一下:只需一行代码就可以将向量打印到控制台。您不必处理带有分隔符的特殊情况。你不需要担心for循环。标准库为您做了所有这些。

#3


58  

In C++11 you can now use a range-based for loop:

在c++ 11中,您现在可以使用基于范围的for循环:

for (auto const& c : path)
    std::cout << c << ' ';

#4


32  

I think the best way to do this is to just overload operator<< by adding this function to your program:

我认为最好的方法就是重载操作符<< <通过将这个函数添加到你的程序中:< p>

#include <vector>
using std::vector;
#include <iostream>
using std::ostream;

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& v) {
    out << "{";
    size_t last = v.size() - 1;
    for(size_t i = 0; i < v.size(); ++i) {
        out << v[i];
        if (i != last) 
            out << ", ";
    }
    out << "}";
    return out;
}

Then you can use the << operator on any possible vector, assuming its elements also have ostream& operator<< defined:

然后可以在任何可能的向量上使用< <运算符,假设它的元素也有ostream&operator <已定义:< p>

vector<string>  s = {"first", "second", "third"};
vector<bool>    b = {true, false, true, false, false};
vector<int>     i = {1, 2, 3, 4};
cout << s << endl;
cout << b << endl;
cout << i << endl;

Outputs:

输出:

{first, second, third}
{1, 0, 1, 0, 0}
{1, 2, 3, 4}

#5


13  

How about for_each + lambda expression:

for_each + lambda表达式:

#include <vector>
#include <algorithm>
...
std::vector<char> vec;
...
std::for_each(
              vec.cbegin(),
              vec.cend(),
              [] (const char c) {std::cout << c << " ";} 
              );
...

Of course, a range-based for is the most elegant solution for this concrete task, but this one gives many other possibilities as well.

当然,基于范围的for是这个具体任务最优雅的解决方案,但是这个解决方案也提供了许多其他的可能性。

Explanation

解释

The for_each algorithm takes an input range and a callable object, calling this object on every element of the range. An input range is defined by two iterators. A callable object can be a function, a pointer to function, an object of a class which overloads () operator or as in this case, a lambda expression. The parameter for this expression matches the type of the elements from vector.

for_each算法接受一个输入范围和一个可调用对象,在范围的每个元素上调用这个对象。输入范围由两个迭代器定义。可调用对象可以是函数、指向函数的指针、重载()运算符的类的对象,也可以是lambda表达式。这个表达式的参数与vector中的元素的类型匹配。

The beauty of this implementation is the power you get from lambda expressions - you can use this approach for a lot more things than just printing the vector.

这种实现的美妙之处在于您可以从lambda表达式中获得强大的功能——您可以使用这种方法做更多的事情,而不仅仅是打印向量。

#6


7  

The problem is probably in the previous loop: (x = 17; isalpha(firstsquare); x++). This loop will run not at all (if firstsquare is non-alpha) or will run forever (if it is alpha). The reason is that firstsquare doesn't change as x is incremented.

问题可能在前面的循环中:(x = 17;isalpha(firstsquare);x + +)。这个循环将不会运行(如果firstsquare是非alpha),或者将永远运行(如果它是alpha)。原因是firstsquare不会随着x的增加而改变。

#7


5  

Just copy the container to the console.

只需将容器复制到控制台。

std::vector<int> v{1,2,3,4};
std::copy(v.begin(),v.end(),std::ostream_iterator<int>(std::cout, " " ));

Should output :

应该输出:

1 2 3 4

#8


3  

In C++11, a range-based for loop might be a good solution:

在c++ 11中,基于范围的for循环可能是一个很好的解决方案:

vector<char> items = {'a','b','c'};
for (char n : items)
    cout << n << ' ';

Output: a b c

输出:a b c

#9


2  

I see two problems. As pointed out in for (x = 17; isalpha(firstsquare); x++) there's either an infinite loop or never executed at all, and also in if (entrance == 'S') if the entrance character is different than 'S' then nothing in pushed to the path vector, making it empty and thus printing nothing on screen. You can test the latter checking for path.empty() or printing path.size().

我看到两个问题。如式(x = 17)所示;isalpha(firstsquare);x++)要么是无限循环,要么根本就没有执行,如果入口字符与“S”不同,那么就没有什么东西被推到路径矢量上,使它为空,从而在屏幕上不打印任何东西。您可以测试后一个检查路径.empty()或打印路径.size()。

Either way, wouldn't it be better to use a string instead of a vector? You can access the string contents like an array as well, seek characters, extract substrings and print the string easily (without a loop).

不管怎样,使用字符串而不是向量是不是更好?您还可以像访问数组一样访问字符串内容、查找字符、提取子字符串并轻松打印字符串(无需循环)。

Doing it all with strings might be the way to have it written in a less convoluted way and easier to spot the problem.

使用字符串来完成所有这些操作,可能是一种让它以一种不那么复杂、更容易发现问题的方法。

#10


2  

overload operator<<:

重载操作符< <:

template<typename OutStream, typename T>
OutStream& operator<< (OutStream& out, const vector<T>& v)
{
    for (auto const& tmp : v)
        out << tmp << " ";
    out << endl;
    return out;
}

Usage:

用法:

vector <int> test {1,2,3};
wcout << test; // or any output stream

#11


1  

This answer is based on the answer from Zorawar, but i couldn't leave a comment there.

这个答案是基于Zorawar的回答,但是我不能在那里留下任何评论。

You can make the auto (C++11)/typedef version const by using cbegin and cend instead

您可以使用cbegin和来代替auto (c++ 11)/typedef版本const

for (auto i = path.cbegin(); i != path.cend(); ++i)
    std::cout << *i << ' ';

#12


1  

Using std::copy but without extra trailing separator

An alternative/modified approach using std::copy (as originally used in @JoshuaKravtiz answer) but without including an additional trailing separator after the last element:

使用std::copy(最初用于@JoshuaKravtiz answer)替代/修改的方法,但是在最后一个元素之后不包含附加的尾随分隔符:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

template <typename T>
void print_contents(const std::vector<T>& v, const char * const separator = " ")
{
    if(!v.empty())
    {
        std::copy(v.begin(),
                  --v.end(),
                  std::ostream_iterator<T>(std::cout, separator));
        std::cout << v.back() << "\n";
    }
}

// example usage
int main() {
    std::vector<int> v{1, 2, 3, 4};
    print_contents(v);      // '1 2 3 4'
    print_contents(v, ":"); // '1:2:3:4'
    v = {};
    print_contents(v);      // ... no std::cout
    v = {1};
    print_contents(v);      // '1'
    return 0;
}

Example usage applied to container of a custom POD type:

应用于自定义POD类型容器的示例用法:

// includes and 'print_contents(...)' as above ...

class Foo
{
    int i;
    friend std::ostream& operator<<(std::ostream& out, const Foo& obj);
public:
    Foo(const int i) : i(i) {}
};

std::ostream& operator<<(std::ostream& out, const Foo& obj)
{
    return out << "foo_" << obj.i; 
}

int main() {
    std::vector<Foo> v{1, 2, 3, 4};
    print_contents(v);      // 'foo_1 foo_2 foo_3 foo_4'
    print_contents(v, ":"); // 'foo_1:foo_2:foo_3:foo_4'
    v = {};
    print_contents(v);      // ... no std::cout
    v = {1};
    print_contents(v);      // 'foo_1'
    return 0;
}

#13


0  

In C++11``

在c++中11 ' '

for (auto i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';

for(int i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';