所以,我正在开始使用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
作为旁注,我不知道如何创建一个包含许多不同数据类型的数组,例如整数,字符串等,所以如果有人可以启发我,那就太好了! 感谢您回答我那些非常明显/无趣的问题!
答案 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<<
无缝链接输出流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";
}
答案 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;
}