【问题标题】:C++,Selecting from 2d array based on value-entryC++,基于值输入从二维数组中选择
【发布时间】:2012-12-14 08:34:15
【问题描述】:

我正在使用softflowd+nfdump 创建 netflow 数据并将这些数据存储在二维(字符串)数组中

flows = new string *[flows_len];
for (int i=0;i<flows_len;i++)
{
    flows[i] = new string[47];
}

我正在用 C++ 编写。数组中的每一“行”代表一个流记录,47是nfdump显示的netflow数据不同字段的个数。

我想在每个 IP 的基础上创建一些统计信息(例如,每个 IP 有多少连接流),但我不知道如何获得具有相同 IP 的那些行流(值为srcip 存储在流[j][4] 中,我是 c++ 新手)。

提前致谢!

【问题讨论】:

    标签: c++ arrays select netflow


    【解决方案1】:

    老实说,我会考虑重新考虑您的容器。以下使用标准库数组、向量和多图来完成我认为您正在寻找的内容。示例代码仅使用字符串“A”、“B”或“C”以及三个 IP 地址之一填充表行。您应该特别注意的部分是使用 multimap 来根据 IP 地址索引您的表(尽管它可以很容易地改装为对任意列执行相同的操作)。

    注意:有 很多 人比我更精通 std lib 算法、函数和容器的使用。这只是为了让您了解多映射如何帮助您可能的解决方案。

    EDIT OP 想查看表中 IP 地址的计数,此代码已修改为 main() 函数的尾部。还更新为不使用 C++11 功能。希望更接近 OP 可以使用的东西。

    #include <iostream>
    #include <iterator>
    #include <algorithm>
    #include <functional>
    #include <map>
    #include <vector>
    #include <string>
    using namespace std;
    
    // some simple decls for our info, table, and IP mapping.
    typedef std::vector<std::string> FlowInfo;
    typedef std::vector<FlowInfo> FlowTable;
    
    // a multi-map will likely work for what you want.
    typedef std::multimap<std::string, const FlowInfo* > MapIPToTableIndex;
    
    // a map of IP string-to-unsigned int for counting occurrences.
    typedef std::map<std::string, unsigned int> MapStringToCount;
    
    int main(int argc, char *argv[])
    {
        // populate your flow table using whatever method you choose.
        //  I'm just going to push 10 rows of three ip addresses each.
        FlowTable ft;
        for (size_t i=0;i<10;++i)
        {
            FlowInfo fi(47); // note: always fixed at 47.
    
            for (size_t j=0;j<fi.size();++j)
                fi[j] = "A";
            fi[0][0]+=i;
            fi[4] = "192.168.1.1";
            ft.push_back(fi);
    
            for (size_t j=0;j<fi.size();++j)
                fi[j] = "B";
            fi[0][0]+=i;
            fi[4] = "192.168.1.2";
            ft.push_back(fi);
    
            for (size_t j=0;j<fi.size();++j)
                fi[j] = "C";
            fi[0][0]+=i;
            fi[4] = "192.168.1.3";
            ft.push_back(fi);
        }
    
        // map by IP address into something usefull.
        MapIPToTableIndex infomap;
        for (FlowTable::const_iterator it = ft.begin(); it != ft.end(); ++it)
            infomap.insert(MapIPToTableIndex::value_type((*it)[4], &*it));
    
    
        // prove the map is setup properly. ask for all items in the map
        //  that honor the 192.168.1.2 address.
        for (MapIPToTableIndex::const_iterator it = infomap.lower_bound("192.168.1.2");
             it != infomap.upper_bound("192.168.1.2"); ++it)
        {
            std::copy(it->second->begin(), it->second->end(),
                      ostream_iterator<std::string>(cout, " "));
            cout << endl;
        }
    
        // mine the IP occurance rate from the table:
        MapStringToCount ip_counts;
        for (FlowTable::const_iterator it= ft.begin(); it!=ft.end(); ++it)
            ++ip_counts[ (*it)[4] ];
    
        // dump IPs by occurrence counts.
        for (MapStringToCount::const_iterator it = ip_counts.begin();
             it != ip_counts.end(); ++it)
        {
            cout << it->first << " : " << it->second << endl;
        }
    
        return 0;
    }
    

    输出

    B B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
    C B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
    D B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
    E B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
    F B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
    G B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
    H B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
    I B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
    J B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
    K B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
    192.168.1.1 : 10
    192.168.1.2 : 10
    192.168.1.3 : 10
    

    【讨论】:

    • 这看起来很不错!但是如果我不知道IP怎么办?如果我正在监视一个接口并且我想计算每个单独的未知 IP 有多少个连接?另外,因为二维数组对我来说更容易,我可以在没有向量的情况下做到这一点吗?地图需要矢量吗?
    • @drazenmozart 该向量的目的是明确允许您根据需要添加任意数量的行。如果您想使用固定数组,完全取决于您。由于我不熟悉您对“未知”IP 地址的定义,我只能推测您正在寻找的精确输出。您想要一个唯一地址的 IP 列表及其在表中的出现次数吗?你会惊讶于从你的桌子上挖出来是多么容易。
    • @drazenmozart 更新以从FlowTable 实例中挖掘IP 发生率。希望这就是您想要的。
    • 你是对的,对不起,再次不清楚,对不起我可怜的c++!如果我的 nfdump 文件有,例如 40 个不同 IP 的 500 个流,我想为每个 IP 创建包含所有流的新数组,这样我就可以为每个单独的 IP 地址(流数、传输的字节数等)进行统计。而且我需要它实时运行,所以我不知道 IP 地址,也无法请求特定 IP 地址的流。我希望这很清楚:)
    • 我收到 #include 错误:在 /usr/include/c++/4.6/array:35:0 包含的文件中,来自 main.cpp:8: i' m 在 ubuntu 12 中使用 netbeans。
    【解决方案2】:

    这是一个非常非常简单的例子

    #include <vector>
    #include <string>
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <algorithm>
    #include <iterator>
    
    using namespace std;
    
    typedef vector< string > StatInfo; // 47 enries
    
    void print_stat_by_ip( const vector< StatInfo > & infos, const string & ip ) {
        for ( int i = 0, count = infos.size(); i < count; i++ ) {
            const StatInfo & info = infos[ i ];
            if ( info[ 4 ] == ip ) {
                copy( info.begin(), info.end(), ostream_iterator< string >( cout, ", " ) );
                cout << endl;
            }
        }
    }
    
    int main()
    {
        vector< StatInfo > infos;
    
        for ( int i = 0; i < 10; i++ ) {
            StatInfo info;
            for ( int j = 0; j < 47; j++ ) { // just filling them "0", "1", "2", ... , "46"
                char c_str[ 42 ];
                sprintf( c_str, "%d", j ); 
                info.push_back( c_str );
            }
            char c_str[ 42 ];
            sprintf( c_str, "%d", rand() % 10 );
            info[ 4 ] = c_str;          // this will be an IP-address
            infos.push_back( info );
    
            copy( info.begin(), info.end(), ostream_iterator< string >( cout, ", " ) );
            cout << endl;
        }
    
        string ip_to_find = "5";
        cout << "----------------------------------------" << endl;
        cout << "stat for " << ip_to_find << endl;
        cout << "----------------------------------------" << endl;
        print_stat_by_ip( infos, ip_to_find );
    }
    

    你可以在这里找到 http://liveworkspace.org/code/3AAye8

    【讨论】:

      猜你喜欢
      • 2016-04-22
      • 2016-12-20
      • 1970-01-01
      • 1970-01-01
      • 2014-05-21
      • 1970-01-01
      • 2014-11-17
      • 2018-11-11
      • 1970-01-01
      相关资源
      最近更新 更多