如果我尝试打印值,C strtok将正常工作,但是如果我尝试传递值,则会出现分段错误和null void read_条目(){ 整数计数=0; 对于(int i=0;i

如果我尝试打印值,C strtok将正常工作,但是如果我尝试传递值,则会出现分段错误和null void read_条目(){ 整数计数=0; 对于(int i=0;i,c,C,我有一个函数,它解析一条线并从中获取ip。当我执行以下操作时,它会完全按照我的预期打印。但是,如果我试图将ip传递给函数,就会出现分段错误。即使在我的printf行下面有一个函数,也会导致printf为ip的值打印null。这怎么可能?如何才能使用ip值?strtok返回一个必须立即使用或复制的缓冲区,该缓冲区绑定到第一个初始化缓冲区 在将其返回/传递给函数之前制作一个这样的副本来修复它(顺便说一句,我添加了更多语法检查): 注意:strtok的工作方式令人惊讶(不可重入,具有记忆效应),因此存

我有一个函数,它解析一条线并从中获取ip。当我执行以下操作时,它会完全按照我的预期打印。但是,如果我试图将ip传递给函数,就会出现分段错误。即使在我的printf行下面有一个函数,也会导致printf为ip的值打印null。这怎么可能?如何才能使用ip值?

strtok
返回一个必须立即使用或复制的缓冲区,该缓冲区绑定到第一个初始化缓冲区

在将其返回/传递给函数之前制作一个这样的副本来修复它(顺便说一句,我添加了更多语法检查):


注意:
strtok
的工作方式令人惊讶(不可重入,具有记忆效应),因此存在许多类似的错误。

@M.M;我有一个可怕的疑问:我最初写的是错的。原始代码可以工作。只是您必须复制strtok返回的最后一个字符串,否则当原始缓冲区超出范围/缓冲区的值被覆盖时,值可能会被破坏。我对我的答案进行了大量编辑。这个问题缺少答案,也许我应该避免回答这个问题。当你将ip传递给strdupI时,这仍然会导致分割错误。我可能已经被strdup搞糊涂了。。。您能在调用strdup之前打印ip吗。你的台词真的很长吗?因为声明一个1024字节的缓冲区并读取1024字节并不保证空终止。printf以我正在尝试的格式打印ip,如果strdup不存在。但是,如果strdup在那里,printf在它上面,那么它在这里可以打印(null)。您可以创建一个测试(使用一个只包含上面一行的文件进行测试)并查看它是否崩溃。然后用这些信息来回答你的问题。如果你展示了几行数据样本(可能是“
word1-word2-machine.example.com 69.12.26.238:80
”或类似的东西),这将是明智的。另外,您的
read_entries()
函数依赖于许多全局变量;您可以通过拆分代码来改进代码的因式分解。这将有助于简化MCVE()。
good_data()
函数正在使用一个全局变量
ip
,而没有使用局部变量
p
,这也令人费解。@JonathanLeffler p的东西肯定是一个打字错误。@Jean-Françoisfare:可能吧,但是复制粘贴怎么会失败呢?显示非编译代码并不是一个特别好的主意-我给出了一个慈善的解释(它编译是因为有一个全局变量使它工作),但无论是未定义的全局变量还是拼写错误都不是一个好主意。应该是*ip。我没有全局变量ip。我对C非常陌生,大约一周前读过C编程书。我习惯了更高级的语言,在C语言中处理数组是一件痛苦的事情。我发现把东西推到数组上的例子使用全局变量,所以我就是这样设置数组的。@JonathanLeffler同意。我倾向于粘贴我想要分析的代码。我避免将其发送到打印机并在有问题的小部件中重新键入。顺便问一下,您是否同意声明1024个缓冲区并像上面那样读取1024个字节并不保证空终止?下面我有一个我不太引以为傲的答案,因为它不能解决问题。所以,现在我正努力争取选票。
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;
}
  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.