2012-07-13 58 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); 
    } 
} 
相關問題