使用strtok_r时出现分段错误

时间:2010-02-09 06:24:18

标签: c segmentation-fault strtok

在下面的例子中,有人可以解释为什么我会出现分段错误吗?

#include <stdio.h>
#include <string.h>

int main(void) {
  char *hello = "Hello World, Let me live.";
  char *tokens[50];
  strtok_r(hello, " ,", tokens);
  int i = 0;
  while(i < 5) {
    printf("%s\n", tokens[i++]);
  }
}

6 个答案:

答案 0 :(得分:24)

试试这个:

#include <stdio.h>
#include <string.h>

int main(void) {
        char hello[] = "Hello World, Let me live."; // make this a char array not a pointer to literal.
        char *rest; // to point to the rest of the string after token extraction.
        char *token; // to point to the actual token returned.
        char *ptr = hello; // make q point to start of hello.

        // loop till strtok_r returns NULL.
        while(token = strtok_r(ptr, " ,", &rest)) {

                printf("%s\n", token); // print the token returned.
                ptr = rest; // rest contains the left over part..assign it to ptr...and start tokenizing again.    
        }
}
/*
Output:
Hello
World
Let
me
live.
*/

答案 1 :(得分:16)

  • 您需要在循环中调用strtok_r。第一次给它提供要标记化的字符串,然后将它作为第一个参数给它NULL
  • strtok_rchar **作为第三个参数。 tokens是一个包含50个char *值的数组。当您将tokens传递给strtok_r()时,传递的是char **值,该值指向该数组的第一个元素。这没关系,但是你浪费了49个根本没用过的值。您应该char *last;并使用&last作为strtok_r()的第三个参数。
  • strtok_r()修改了它的第一个参数,因此您无法将其传递给无法修改的内容。 C中的字符串文字是只读的,因此您需要一些可以修改的内容:例如char hello[] = "Hello World, Let me live.";

答案 2 :(得分:5)

一堆错误:

  1. hello指向字符串文字,必须将其视为不可变。 (它可以存在于只读内存中。)由于strtok_r会改变其参数字符串,因此您无法使用hello

  2. 您只需拨打一次strtok_r,并且不会初始化tokens数组以指向任何内容。

  3. 试试这个:

    #include <stdio.h>
    #include <string.h>
    
    int main(void) {
      char hello[] = "Hello World, Let me live.";
      char *p = hello;
      char *tokens[50];
      int i = 0;
    
      while (i < 50) {
         tokens[i] = strtok_r(p, " ,", &p);
         if (tokens[i] == NULL) {
            break;
         }
         i++;
      }
    
      i = 0;
      while (i < 5) {
        printf("%s\n", tokens[i++]);
      }
    
      return 0;
    }
    

答案 3 :(得分:3)

strtok_r尝试将空字符写入hello(这是非法的,因为它是一个const字符串)

答案 4 :(得分:2)

您已正确理解strtok_r的用法。请查看此example和文档

尝试&amp;看到这个:

#include <stdio.h>
#include <string.h>    

int main(void)
{
    char hello[] = "Hello World, let me live.";

    char *tmp;
    char *token = NULL;
    for(token = strtok_r(hello, ", ", &tmp);
        token != NULL;
        token = strtok_r(NULL, ", ", &tmp))
    {
        printf("%s\n", token);
    }

    return 0;
}

答案 5 :(得分:0)

我认为它可能是char *tokens[50];,因为当它已经是指针时你将它指定为指针。数组已经是声明时的指针。你的意思是说char tokens[50];。这应该可以解决问题。