2016-10-02 23 views
-2
void read_entries() { 
    int count = 0; 
    for (int i = 0; i < top; i++) { 
    FILE *fp; 
    fp = fopen(File_List[i], "r"); 
    char buff[1024]; 

    while (fgets(buff, 1024, fp) != NULL) { 
     if (good_data(buff)) { 
     count++; 
     } 

    } 

    fclose(fp); 
    } 
} 


int good_data(char* buff) { 
     char *ip; 
     ip = strtok (buff, " "); 
     ip = strtok (NULL, " "); 
     ip = strtok (NULL, " "); 
     ip = strtok (ip, ":"); 

     printf("IP below\n"); 
     printf("%s\n", ip); 
     //strcmp(ip, "69.12.26.238"); 
     return 0; 
} 

我有這個功能,解析一條線,並抓住它的IP。當我按照以下步驟進行打印時,完全如我所料。但是,如果我嘗試將該ip傳遞給函數,則會出現分段錯誤。即使通過在我的printf行下面有一個函數,printf也會爲ip值輸出null。這怎麼可能?我能做些什麼才能使用ip值?C strtok工作,如果我嘗試打印值,但分段錯誤,如果我試圖通過值爲空

+0

如果您顯示了幾條樣本行數據(可能是「word1 word2 machine.example.com 69.12.26.238:80」或類似的東西),這將是明智的。另外,你的'read_entries()'函數依賴於一些全局變量;將代碼分解,可以改善代碼的分解。這將有助於使MCVE([MCVE])更簡單。 'good_data()'函數使用全局變量'ip',而不使用局部變量'p',這也是令人費解的。 –

+0

@JonathanLeffler這件事肯定是一個錯字。 –

+0

@ Jean-FrançoisFabre:可能,但是copy'n'paste是如何失敗的?顯示非編譯代碼並不是一個特別好的主意 - 我給出了慈善解釋(它編譯是因爲有一個全局變量使它起作用),但是在SO的問題中,既沒有定義的全局錯誤也沒有錯別字是一個好主意。 –

回答

1

strtok返回一個緩衝區,您必須立即使用或複製綁定到第一個初始化緩衝區的緩衝區。

修復它通過只返回它/它傳遞給一個函數之前做出這樣的副本(我已經添加BTW多個語法檢查):

char *ip,*ip_copy; 
    ip = strtok (buff, " "); 
    ip = strtok (NULL, " "); 
    if (ip == NULL) return -1; 
    ip = strtok (NULL, " "); 
    if (ip == NULL) return -1; 
    ip = strtok (ip, ":"); 
    if (ip == NULL) return -1; 

    ip_copy = strdup(ip); // now you have a solid copy of the string, that has a global scope. 

注:也有很多類似錯誤的因令人驚訝的方式strtok作品(不可重入,具有記憶效應)。

+0

@ M.M;我有一個可怕的疑問:我寫的第一個地方是錯誤的。原始代碼有效。只是必須複製'strtok'返回的最後一個字符串,否則當原始緩衝區超出範圍/緩衝區的值被覆蓋時,該值可能會被丟棄。我大量編輯了我的答案。這個問題沒有[mcve],也許我應該避免回答這個問題。 –

+0

只要您將ip傳遞給strdup,這仍然會導致分段錯誤 – Steve

+0

我可能已經被strdup帶走了......您是否可以在調用'strdup'之前printf ip?你的線路真的很長嗎?因爲聲明1024的緩衝區並讀取1024個字節不保證空終止。 –

相關問題