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

时间:2013-06-22 07:34:31

标签: c++

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

x = [1, 2, 3, 4, 5, 6, 7, 8, 9]

然后,要打印列表,包含方括号,您只需:

print x

这会显示:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

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

{1, 2, 3, 4, 5, 6, 7, 8, 9}

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

输入:

#include <iostream>
using namespace std;


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

}

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

0x28fedc

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

6 个答案:

答案 0 :(得分: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";
}

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

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

这个解决方案可以简单地推广到处理范围和标准库容器。有关更一般的方法,请参阅here

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

答案 1 :(得分: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";

印刷

Woot, I can has { hello, bye } and even { 1:2:3:42 }!

请注意

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

    std::cout << "or bizarrely: " << print(arr, print(arr)) << "\n";
    

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

    or bizarrely: { hello{ hello, bye }bye }
    

    如果你问我,仍然可以证明无缝连接进入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";
}

现场观看 http://ideone.com/E4G9Fp

答案 2 :(得分:2)

for(int i=0;i<9;i++)
cout << anArray[i] << endl;

啊,好的括号就是这样(简单的数组阵列打印逻辑,你可以在将来使它更通用)

  cout<<'{';
    for(int i=0;i<8;i++)
           cout << anArray[i] <<','; 
    cout<<anArray[8]<<'}';

对于python用户和 c ++爱好者,有std :: vector。

这里是矢量的打印逻辑 //使用[]运算符

的解决方案
if(anVector.size()>=1){
     std::cout<<"{";
      for(int i=0;i<anVector.size()-1;i++){
            std::cout<<anVector[i]<<',' ; 

      }
    std::cout<<anVector[anVector.size()-1]<<'}' ; 
}

//使用迭代器的解决方案

  std::vector<int>::iterator it =anVector.begin();
       if(it!=anVector.end()){ 
            std::cout << '{'<<*it;
            ++it;
            for (; it != anVector.end(); ++it){
               std::cout<<','<< *it ; 
            }
            std::cout << '}';
        }

同时检查C ++ 11 std :: vector。在新的标准初始化和其他更优雅的事情

答案 3 :(得分:1)

可能最简单的方法是将数组打印得很好(假设它的长度大于零)可能是这样的:

std::cout << "{" << anArray[0];
for (int i = 1; i < sizeof (anArray) / sizeof (*anArray); i++)
    std::cout << ", " << array[i];
std::cout << "}";

如果您希望能够打印 less 而不是完整数组,则需要一种方法来指定长度(可能为零,因此您应该处理这种情况:

if (length == 0)
    std::cout << "{}";
else {
    std::cout << "{" << anArray[0];
    for (int i = 1; i < length; i++)
        std::cout << ", " << array[i];
    std::cout << "}";
}

可能还有其他的变化,例如在给定的起始点而不是元素零点进行打印,但我不会在此处讨论。可以说,这只是对循环和if条件的一个小修改。

当然,如果你想以简单的方式做到这一点,std::cout << myvariable;,你可以考虑将整个事物包装在一个类中并为它提供你自己的operator<< - 这将是一个更多面向对象的服务方式。

答案 4 :(得分:1)

如果你不太关心将逗号作为分隔符,你也可以使用输出迭代器

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

...

int anArray[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

std::cout << "{ ";
std::copy(anArray, anArray + 9, std::ostream_iterator<int>(std::cout, " "));
std::cout << "}" << std::endl;

答案 5 :(得分:0)

另一个实现此目的的方法是定义一个宏,将c数组转换为std :: vector,并使用一个模板函数输出std :: vector,如下所示:

#include <vector>
#include <iostream>

// convert an array (e.g. int32_t x[20]) into an std::vector
#define ARRAY_TO_STD_VECTOR(VAR, TYPE) std::vector<TYPE>(VAR, VAR + sizeof(VAR)/sizeof(TYPE))

// output of std::vector<T>
namespace std {
  template<typename T>
  std::ostream& operator<<(std::ostream& p, const std::vector<T>& v)
  {
    p << "{";
    for (size_t i = 0; i < v.size(); ++i)
    {
      p << v[i];
      if (i < (v.size() - 1)) p << ", ";
    }
    p << "}";
    return p;
  }
}

有了这个,您可以像这样输出数组:

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

}