2015-11-24 9 views
-1

У меня есть файл журнала из 10 ударов, например. одна строка:Подсчитайте, сколько раз IP-номер отображается в текстовом файле - C Программа

127.0.0.1 - - [10/Oct/2007:13:55:36 ­0700]"GET /index.html HTTP/1.0" 200 2326 "http://www.example.com/links.html" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322)" 

Формат каждой строки тот же, то есть IP-адрес всегда находится в начале.

В настоящее время я читаю в файле с помощью fopen и fgets, но теперь я хочу подсчитать, сколько уникальных IP-адресов есть в файле, а также подсчитать, сколько раз IP-образы. Не знаю, как я попытаюсь это сделать. Какие-нибудь советы о том, как я буду заниматься этим?

+1

Это зависит, если формат файла является фиксированным и НУ знать, где искать IP-адреса, или если вам нужно сканировать строки для моделей, которые * просмотровых * как IP-адреса , Это было бы приблизительным, поскольку URL-адреса могут содержать такие шаблоны, создающие ложные срабатывания. – chqrlie

+0

Если IP-адрес всегда в начале, относительно легко проанализировать их с помощью 'sscanf' после проверки правильного формата. – chqrlie

+0

«например ** ** ** строка:« ** 4 ** строки данных? – chux

ответ

2

Код может идти, хотя файл ищет шаблон ddd.ddd.ddd.ddd.

Избегайте использования "%d" или "%u", так как они принимают ведущие пробелы и '-' и '+'.

Псевдокод

Read from a file until EOF found 
    repeatedly look for a digit 
    if it is found 
    note position 
    put digit back into stream 
    look for ddd.ddd.ddd.ddd 
    if found 
     decode (and test for values > 255) 
     if successful return result 
    go back to position 

return fail value; 

Пример кода. Также должна быть проверка ошибок ввода-вывода.

unsigned long Parse_IP(FILE *inf) { 
    int ch; 
    for ((ch = fgetc(inf)) != EOF) { 
    if (isdigit(ch)) { 
     long pos = ftell(inf); 
     ungetc(ch, inf); 
     char buf[4][4]; 
     int count = fscanf(inf, "%3[0-9].%3[0-9].%3[0-9].%3[0-9]", 
      buf[0], buf[1], buf[2], buf[3]); 
     if (count == 4) { 
     unsigned long ip = 0; 
     int i; 
     for (i=0; i<4; i++) { 
      int digit = atoi(buf[i]); 
      if (digit > 255) break; 
      ip = ip*256 + digit; 
     } 
     if (i == 4) return ip; 
     } 
     fseek(inf, pos, SEEK_SET); 
    } 
    } 
    return 0; 
} 

Пример использования

unsigned long ip; 
while ((ip = Parse_IP(inf)) != 0) { 
    printf("ip %08lX\n", ip); 
} 
+0

Ваш код может не работать для трубы или как вы предполагаете, вы можете 'fseek' назад, и он ошибочно будет соответствовать IP-адресам для этих шаблонов:' 9127.0.0.1', '0.0.0.2550' и т. д. – chqrlie

+0

Я придирчивый, но почему бы не принять' 0.0. Как действительный шаблон IP-адреса? – chqrlie

+1

@chqrlie Выложенный метод возвращает 32-битное целое число, используя значение _some_ в качестве индикатора отказа. Код может быть легко изменен, чтобы вернуть «длинный длинный» с -1 в качестве плохого мальчика или сохранить IP-адрес в переданном месте указателя и вернуть значение «int» или 0 или 1. '0' казалось естественным выбором для« недействительных стоимость". Нет веских причин для '0' – chux