C ++, выбор из 2d массива на основе ввода значения

я использую softflowd+nfdump создать данные netflow и сохранить эти данные в 2d (строковом) массиве

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

Я пишу на С ++. Каждая «строка» в массиве представляет запись потока, а 47 — количество различных полей данных сетевого потока, отображаемых с помощью nfdump.

Я хотел бы создать некоторую статистику для каждого IP-адреса (например, сколько потоков соединений существует на один IP-адрес), но я не могу понять, как получить эти строки-потоки с тем же IP-адресом (значение srcip сохраняется в потоках [J] [4], и я новичок в C ++).

заранее спасибо!

3

Решение

Это очень, очень, очень простой пример

#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

1

Другие решения

Честно говоря, я бы пересмотрел ваши контейнеры. Следующее использует стандартный массив lib, vector и multimap для выполнения того, что, я думаю, вы ищете. Пример кода просто заполняет строки таблицы строками «A», «B» или «C» вместе с одним из трех IP-адресов. Частью, на которую вы должны обратить особое внимание, является использование мультикарты для индексации таблицы на основе IP-адреса (хотя ее можно легко модифицировать, чтобы сделать то же самое для любого произвольного столбца).

Примечание: есть много из людей, более опытных в использовании алгоритмов, функций и контейнеров std lib, чем я. Это просто, чтобы дать вам представление о том, как мультикарта может помочь в вашем возможном решении.

РЕДАКТИРОВАТЬ ОП хотел видеть количество 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
1

По вопросам рекламы [email protected]