2015-11-24 43 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

這取決於如果文件格式是固定和OU知道在哪裏查找IP地址,或者如果您需要掃描模式,*外觀*如IP地址線。這將是近似值,因爲URL可能包含產生誤報的模式。 – chqrlie

+0

如果IP地址始終在開頭,那麼在檢查正確的格式後,用'sscanf'解析它們是相對容易的。 – chqrlie

+0

「例如** 1 ** **行是:** ** ** **行數據? – 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; 

示例代碼。還應該有IO錯誤檢查。

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。 0.0'作爲一個有效的IP地址模式? – chqrlie

+1

@chqrlie發佈的方法返回一個32位整數,使用_some_值作爲失敗指示。代碼可以很容易地修改爲返回一個'long long'作爲壞男孩,或者將IP地址保存在傳遞的指針位置並返回一個'int'或者0或1.'0'似乎是「無效的值」。沒有令人信服的理由'0' – chux

相關問題