2016-10-02 43 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个字节不保证空终止。 –

相关问题