如何打印向量的内容? [英] How do I print out the contents of a vector?

查看:71
本文介绍了如何打印向量的内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将 std :: vector 的内容打印到屏幕上?

How do I print out the contents of a std::vector to the screen?

实现以下 operator<< 的解决方案也是不错的选择:

A solution that implements the following operator<< would be nice as well:

template<container C, class T, String delim = ", ", String open = "[", String close = "]">
std::ostream & operator<<(std::ostream & o, const C<T> & x)
{
  // ... What can I write here?
}


这是我到目前为止所拥有的,没有单独的功能:


Here is what I have so far, without a separate function:

#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;
    }
}

推荐答案

您可以使用迭代器:

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

如果要在for循环中修改向量的内容,请使用 iterator 而不是 const_iterator .

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.

这不是另一个解决方案,而是对上述 iterator 解决方案的补充.如果您使用的是C ++ 11标准(或更高版本),则可以使用 auto 关键字来提高可读性:

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 << ' ';

但是 i 的类型将是非常量的(即,编译器将使用 std :: vector< char> :: iterator 作为的类型> 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).

在这种情况下,您最好只使用 typedef ,它也带来了自己的好处(我将在这里不予赘述):

In this case, you might as well just use a typedef, which also brings with it its own benefits (which I won't expound upon here):

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

C ++ 11还引入了类型别名,该别名与typedef的作用相同,与使用typedef相比,您可能会发现可读性更高:

C++11 also introduced a type alias, which does the same job as a typedef and you may find more readable than using typedef:

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

计数器

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

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

如果要执行此操作,则最好使用容器的成员类型(如果有的话). std :: vector 具有用于此作业的成员类型,称为 size_type :这是 size 方法返回的类型.

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.

// Path typedef'd to std::vector<char>
for( Path::size_type i=0; i<path.size(); ++i)
  std::cout << path[i] << ' ';

为什么不仅仅在 iterator 解决方案上使用它?对于简单的情况,您也可能会这样做,但要点是, iterator 是一个对象,旨在针对较复杂的对象执行此任务,而该解决方案并不理想.

Why not just use this over the iterator solution? For simple cases you might as well, but the point is that an iterator is an object designed to do this job for more complicated objects where this solution is not going to be ideal.

请参见 Jefffrey的解决方案.在C ++ 11(及更高版本)中,您可以使用新的基于范围的 for 循环,如下所示:

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 << ' ';

由于 path 是项的向量(明确表示为 std :: vector< char> ),因此对象 i 的类型为向量的项(即,显式地,其类型为 char ).对象 i 的值是 path 对象中实际项目的副本.因此,循环中对 i 的所有更改都不会保留在 path 本身中.此外,如果您要强制执行以下事实:不想在循环中更改 i 的复制值,则可以强制使用 i 成为这样的 const char :

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 << ' ';

如果要修改 path 中的项目,可以使用参考:

If you would like to modify the items in path, you can use a reference:

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

即使您不想修改 path ,如果对象的复制成本很高,您也应该使用const引用而不是按值复制:

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 << ' ';

std :: copy(C ++ 11)

请参见约书亚的答案.您可以使用STL算法 std :: copy 将矢量内容复制到输出流上.如果您愿意的话,这是一个优雅的解决方案.应该鼓励更加熟悉STL算法,并且它们提供了许多功能,初学者可能会陷入重创.阅读Joshua的帖子以获取更多信息.

std::copy (C++11)

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. Getting more familiar with STL algorithms should be encouraged, and they provide a lot of functionality that beginners may fall into reinventing themselves. Read Joshua's post for more info.

请参见克里斯的答案,这是对其他答案的补充,因为您仍然需要实施以下方法之一以上解决方案在重载中.在他的示例中,他在 for 循环中使用了一个计数器.例如,这是您可以快速使用 Joshua的解决方案的方法:

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:

#include <iterator> // needed for std::ostram_iterator

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;
}

使用任何其他解决方案应该同样简单.

Using any of the other solutions should be equally 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.

这是我发布的较早版本的扩展解决方案.由于该帖子一直受到关注,因此我决定对其进行扩展,并参考此处发布的其他出色解决方案.我的原始帖子中有一条评论提到,如果您打算在 for 循环中修改向量,那么 std :: vector 访问元素: std :: vector :: operator [] 不执行边界检查,而 std :: vector :: at 执行边界检查.换句话说,如果您尝试访问向量外部的元素,则 at 将会抛出,而 operator [] 则不会.我最初仅添加此评论是为了提及一些可能对了解是否有人已经有用的信息.我现在看不出任何区别.因此,此附录.

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.

这篇关于如何打印向量的内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆