我正在解析来自“仅C”接口的文本数组,其中每个字符串可能具有任意数量的值,可以通过“istream::operator >>()
”进行单独解析。
例如,其中一个解析器用于自定义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 *
将所有字符串(stringstream
)与所有字符串进行对接,然后使用我的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。
答案 0 :(得分: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));
答案 1 :(得分: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 );
}
}
答案 2 :(得分:1)
std::copy()
和std::back_inserter
肯定是出路。
我坚持,虽然使用for
循环来迭代字符串而不是连接stringstream
中的所有内容,如@ephemient所示:
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
对象,但不必重新定位内存以连接字符串。