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


实现以下操作符<<的解决方案也很好:

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

以下是目前为止我所做的,没有单独的函数:

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

当前回答

对于想要没有循环的一行程序的人:

我不敢相信没有人知道这一点,但也许是因为更像c的方法。不管怎样,在没有循环的情况下,假设std::vector<char>是空终止的,在一行程序中是完全安全的:

std::vector<char> test { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\0' };
std::cout << test.data() << std::endl;

但为了安全起见,我会把它包装在ostream操作符中,就像@Zorawar建议的那样:

template <typename T>std::ostream& operator<< (std::ostream& out, std::vector<T>& v)
{
    v.push_back('\0'); // safety-check!
    out << v.data();
    return out;
}

std::cout << test << std::endl; // will print 'Hello, world!'

我们可以通过使用printf来实现类似的行为:

fprintf(stdout, "%s\n", &test[0]); // will also print 'Hello, world!'

注意:

重载的ostream操作符需要接受非const的vector。这可能会使程序不安全或引入不可用的代码。此外,由于添加了空字符,可能会发生std::vector的重新分配。因此,使用带有迭代器的for循环可能会更快。

其他回答

重载操作符< <:

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

用法:

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

我看到了两个问题。正如在

for (x = 17; isalpha(firstsquare); x++)

要么是一个无限循环,要么根本没有执行,同样在if(入口== 'S')中,如果入口字符与'S'不同,则没有任何东西被推送到路径向量,使其为空,因此在屏幕上不打印任何东西。您可以检查path.empty()或打印path.size()来测试后者。

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

用字符串来完成这一切可能是用一种不那么复杂的方式来编写它,并且更容易发现问题。

从第一个BoostCon(现在叫CppCon)出来,我和另外两个人致力于一个库来实现这一点。主要的问题是需要扩展命名空间std。这对boost库来说是不可能的。

不幸的是,到代码的链接不再工作,但您可能会在讨论中发现一些有趣的花絮(至少那些没有讨论如何命名它!)

http://boost.2283326.n4.nabble.com/explore-Library-Proposal-Container-Streaming-td2619544.html

你可以使用perr.h作为起点:

#include <vector>
#include "perr.h"

int main() {
    std::vector< int > v = { 1, 2, 3 };
    perr << v;
}

你只需要从GitHub (https://github.com/az5112/perr)抓取头。

我认为最好的方法是通过在程序中添加这个函数来重载操作符<<:

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

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

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;

输出:

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