2012-07-13 85 views
1

我解析来自“纯C”接口的文本数组,并且每个字符串可能有任意数量的值,可能孤立地被解析为“istream::operator >>() ”。C++更好的方法来解析值到一个向量

例如,解析器之一是自定义的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-只有”功能。

天真的方法将首先使用stringstream将所有字符串(const char *)控制在一起,然后用我的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

您确定您描述的方法正常吗?您将所有字符串写入没有分隔符的流中,因此您最终可能会得到如下所示的片段:'192.168.0.40169.254.3.18'。 – dasblinkenlight 2012-07-13 19:35:28

+0

是的,你是对的。我会修复我的例子,谢谢。 – j4x 2012-07-13 19:38:24

回答

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对象,但不必重新定位用于连接字符串的内存。

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)); 
+3

'std :: begin(string_array)'和'std :: end(string_array)'也应该用作迭代器限制。 – TemplateRex 2012-07-13 19:46:24

+0

@rhalbersma:如果你有C++ 11,是的。 – ephemient 2012-07-14 00:14:34

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); 
    } 
} 
相关问题