有没有办法在c ++中输出实际的数组

use*_*129 9 c++

所以,我正在开始使用python的半完全背景的C++.在python中,你创建一个像这样的列表/数组:

x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)

然后,要打印列表,包括方括号,您所做的只是:

print x
Run Code Online (Sandbox Code Playgroud)

那会显示出来:

[1, 2, 3, 4, 5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)

我怎样才能在c ++中做同样的事情,以优雅/干净的方式打印括号和元素?注意我不想只是数组的元素,我想要整个数组,如下所示:

{1, 2, 3, 4, 5, 6, 7, 8, 9}
Run Code Online (Sandbox Code Playgroud)

当我使用此代码尝试打印数组时,会发生以下情况:

输入:

#include <iostream>
using namespace std;


int main()
{
    int anArray[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    cout << anArray << endl;

}
Run Code Online (Sandbox Code Playgroud)

输出是内存中存储数组的位置(我想是这样,如果我错了,请纠正我):

0x28fedc
Run Code Online (Sandbox Code Playgroud)

作为旁注,我不知道如何创建一个包含许多不同数据类型的数组,例如整数,字符串等,所以如果有人可以启发我,那就太好了!感谢您回答我那些非常明显/无趣的问题!

jua*_*nza 13

您可以编写一个简单的辅助函数,以允许您将数组流式传输到输出流(包括但不限于std::cout):

#include <iostream>
// print an array to an output stream
// prints to std::cout by default
template <typename T, std::size_t N>
void print_array(const T(&a)[N], std::ostream& o = std::cout)
{
  o << "{";
  for (std::size_t i = 0; i < N-1; ++i)
  {
    o << a[i] << ", ";
  }
  o << a[N-1] << "}\n";
}
Run Code Online (Sandbox Code Playgroud)

其中使用函数模板以便在编译时推导出数组的类型和大小.你可以像这样使用它:

#include <fstream>
int main()
{
  int a[] = {1,2,3,4,5};
  print_array(a); // prints {1, 2, 3, 4, 5} to stdout

  std::string sa[] = {"hello", "world"};
  print_array(sa, std::cerr); // prints {hello, world} to stderr

  std::ofstream output("array.txt");
  print_array(a, output); // prints {1, 2, 3, 4, 5} to file array.txt
}
Run Code Online (Sandbox Code Playgroud)

可以简单地推广该解决方案以处理范围和标准库容器.有关更一般的方法,请参见此处.

至于旁注,你不能用C++做到这一点.数组只能保存一种类型的对象.

  • @raxman你有权得到你的意见.当然,我完全不同意.您现在有一个类型安全函数,可以写入任何输出流. (3认同)
  • 如果数组为空(尝试访问`a [-1]`),则会失败. (2认同)
  • 你可以通过传递迭代器而没有传递array-by-ref的丑陋:`print_joined(",",begin(arr),end(arr))` (2认同)

seh*_*ehe 7

受到juanchopanza和Raxman的答案的启发,我决定做一个真正的IO操纵器,这导致了如下语法:

const char* arr[] = { "hello", "bye" };
std::cout 
    << "Woot, I can has " << print(arr)
    << " and even " << print(std::vector<int> { 1,2,3,42 }, ":") << "!\n";
Run Code Online (Sandbox Code Playgroud)

印花

Woot, I can has { hello, bye } and even { 1:2:3:42 }!
Run Code Online (Sandbox Code Playgroud)

注意

  • 它可以operator<<像往常一样使用链式输出流无缝地工作
  • 它是完全通用的(支持任何可流式传输的容器)
  • 它甚至允许传递分隔符(作为示例)
  • 使用更多的模板参数,它可以做得如此通用,以便使用ostream,wostream等.
  • fun:由于分隔符也可以是任何可流式"东西",你甚至可以......使用数组作为分隔符:

    std::cout << "or bizarrely: " << print(arr, print(arr)) << "\n";
    
    Run Code Online (Sandbox Code Playgroud)

    导致相当奇怪的样本输出:

    or bizarrely: { hello{ hello, bye }bye }
    
    Run Code Online (Sandbox Code Playgroud)

    如果你问我,仍然可以展示无缝连接 IO流的能力.

我相信在C++中它不会比这更加无缝.当然有一些实现要做,但正如你所看到的,你可以利用完全通用性,所以你马上完成了任何可流式类型的容器:

#include <iostream>
#include <vector>

namespace manips
{
    template <typename Cont, typename Delim=const char*>
    struct PrintManip { 
        PrintManip(Cont const& v, Delim d = ", ") : _v(v), _d(std::move(d)) { }

        Cont const& _v;
        Delim _d;

        friend std::ostream& operator<<(std::ostream& os, PrintManip const& manip) {
            using namespace std;
            auto f = begin(manip._v), l(end(manip._v)); 

            os << "{ ";
            while (f != l)
                if ((os << *f) && (++f != l))
                    os << manip._d;
            return os << " }";
        }
    };

    template <typename T, typename Delim=const char*> 
    manips::PrintManip<T, Delim> print(T const& deduce, Delim delim = ", ") { 
        return { deduce, std::move(delim) }; 
    }
}

using manips::print;

int main()
{
    const char* arr[] = { "hello", "bye" };
    std::cout 
        << "Woot, I can has " << print(arr)
        << " and even: " << print(std::vector<int> { 1,2,3,42 }, ':') << "!\n"
        << "or bizarrely: " << print(arr, print(arr)) << "\n";
}
Run Code Online (Sandbox Code Playgroud)

请访问http://ideone.com/E4G9Fp查看