9

だから、私は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

補足として、整数、文字列など、さまざまなデータ型の配列を作成する方法がわからないので、誰かが私を啓発できるなら、それは素晴らしいことです! 私の骨の折れるほど明白な/初心者の質問に答えてくれてありがとう!

4

6 に答える 6

14

単純なヘルパー関数を記述して、配列を出力ストリーム (を含むがこれに限定されない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
}

このソリューションは、範囲と標準ライブラリ コンテナーを処理するために簡単に一般化できます。さらに一般的なアプローチについては、こちらを参照してください。

補足として、C ++ではそれを行うことはできません。配列は、1 つのタイプのオブジェクトのみを保持できます。

于 2013-06-22T07:38:00.103 に答える
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 などで動作するように非常に一般的なものにすることができます。
  • 楽しい:区切り文字はストリーミング可能な任意の「もの」にすることもできるため、配列を区切り文字として使用することもできます。

    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でライブをご覧ください

于 2013-06-24T21:54:33.747 に答える
2
for(int i=0;i<9;i++)
cout << anArray[i] << endl;

ああ、括弧付きでOKです(単に配列の印刷ロジックを配列します。将来的にはより一般的にすることができます)

  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 も確認してください。新しい標準の初期化とその他のよりエレガントな方法で

于 2013-06-22T07:36:52.593 に答える
1

コンマを区切り記号として使用することをあまり気にしない場合は、output iteratorsを使用することもできます。

#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;
于 2013-06-24T22:20:45.593 に答える