1

「C-only」インターフェイスからのテキストの配列を解析しています。各文字列には、「istream::operator >>()」によって単独で解析できる任意の量の値が含まれている可能性があります。

たとえば、パーサーの 1 つはカスタム IPv4 クラス用です。

std::istream &  operator >>( std::istream& stream, IPv4 &var )

実装は非常に明白です。

次のような入力があるとします。

const char *string_array[] =
{
    "192.168.0.1, 192.168.0.32,    192.168.0.40",
    "169.254.3.18, 169.254.3.19, 169.254.3.20, 169.254.3.21",
    "10.0.92.100",
    "10.0.0.101,    10.0.0.102,    10.0.0.103   ,  10.0.0.104 , 10.0.0.110  ",
};

「Cのみ」の関数に送信できるように、解析されたすべての値を配列に入れるエレガントな方法を見つけたいと思います。

単純な方法は、最初にすべての文字列 ( const char *) を aで連結しstringstream、次にこのストリームを my でループすることoperator >>です。

        std::stringstream   ss;
        IPv4 ip;
        std::vector< IPv4 > ip_vector;

         for ( int c = 0; c < count; ++c )
                        ss << string_array[ c ] << ", ";

         while ( ss.good( ) )
         {
                        ss >> ip;
                    ip_vector.push_back( ip );
         }

私にはそれほど賢明ではないように思えますが、これをより賢くする方法がわかりません。

また、注意: Boost はこのソリューションのオプションではありません。

4

3 に答える 3

2

独自のループを記述する代わりに使用できる組み込みの STL 機能があります。

copy(string_array, string_array + count,
     ostream_iterator<const char *>(ss, ", "));
copy(istream_iterator<IPv4>(ss), istream_iterator<IPv4>(),
     back_inserter(ip_vector));
于 2012-07-13T19:38:42.703 に答える
1

std::copy()そしてそれstd::back_inserterは確かに出口です。@ephemient で提案されているようforに、 a 内のすべてを連結するのではなく、文字列を反復するためのループを使用しますが、私は固執します。stringstream

std::vector< IPv4 > ip_vector;

for ( unsigned c = 0; c < count; ++c )
{
    std::stringstream   ss( string_array[ c ] );

    std::copy( std::istream_iterator< IPv4 >( ss ), std::istream_iterator< IPv4 >( ),
                std::back_inserter( ip_vector ) );
}

このようにして、すべての文字列を変換していることを明確にします。また、3 つのオブジェクトを構築する必要がありstd::stringstreamますが、文字列を連結するためにメモリを再配置する必要はありません。

于 2012-07-16T11:34:29.197 に答える
1

私はそれを連結することは役に立たないと思います.単にループを「結合」するだけです.

istream &skipblanks(istream &s) {
  char c;
  while ((c = s.peek()) == ' ' || c == ',')
   s.get();
  return s;
}

...
std::vector< IPv4 > ip_vector;
for ( int c = 0; c < count; ++c ) {
    istringstream ss(string_array[ c ]);
    while (ss) {
        IPv4 ip;
        if (skipblanks(ss) >> ip)
            ip_vector.push_back( ip );
    }
}
于 2012-07-13T20:18:35.203 に答える