将字符串拆分为 C 中的双指针

Split a string into double pointer in C

我正在尝试将字符串(示例:"hey there mister")转换为指向句子中每个单词的双指针。 所以:split_string->|pointer1|pointer2|pointer3|其中 pointer1->"hey"、pointer2->"there" 和 pointer3->"mister".

char **split(char *s) {
    char **nystreng = malloc(strlen(s));
    char str[strlen(s)];
    int i;

    for(i = 0; i < strlen(s); i++){
        str[i] = s[i];
    }

    char *temp;
    temp = strtok(str, " ");

    int teller = 0;
    while(temp != NULL){
        printf("%s\n", temp);
        nystreng[teller] = temp;
        temp = strtok(NULL, " ");
    }
    nystreng[teller++] = NULL;

    //free(nystreng);

    return nystreng;
}

我的问题是,为什么这不起作用?

有两件事你需要做 -

char str[strlen(s)];  //size should be equal to strlen(s)+1

额外 1 '[=12=]'。现在你将 str (未以 '[=12=]' 终止)传递给 strtok ,这会导致 undefined behavior

第二件事,你还需要为nystring的每个指针分配内存,然后使用strcpy而不是指向temp不要忘记space 表示 nul 终止符 )。

您的代码有多个问题。其中:

  • char **nystreng = malloc(strlen(s)); 就是错的。您需要的 space 的大小是 char * 的大小乘以字符串将被分割成的块数加一(对于 NULL 指针终止符)。

  • 你用从 strtok() 操作 local 数组 str 获得的指针填充 *nystreng。这些指针仅在 str 的生命周期内有效,该生命周期在函数 returns.

  • 时结束
  • 你没有为str中的字符串终止符分配space,你也没有写一个,但你把它传递给strtok()就好像它是一个终止的字符串。

  • 您不会在标记化循环内递增 teller,因此每个标记指针都会覆盖前一个。

这里你有一个根本问题,你不知道在拆分字符串之前会有多少部分。尽管如此,您仍然可以通过计算分隔符的数量并加 1 来获得上限。然后您可以为那么多 char 指针加一个分配 space。或者,您可以构建一个链表来处理标记化的片段,然后仅在知道有多少片段后才分配结果数组。

至于str,如果你想return指向它,就像你所做的那样,那么它也需要动态分配。如果您的平台提供 strdup() 那么您可以使用

char *str = strdup(s);

否则,您需要检查长度,分配足够的 space 和 malloc()(包括终止符 space),并将输入字符串复制到分配的 space,大概是 strcpy()。通常你会想在之后释放字符串,但如果你 returning 指向那个 space.

则不能这样做

另一方面,您可能会考虑 return 可以 单独 释放的字符串数组。为此,您必须单独分配每个子字符串(strdup() 将再次成为您的朋友,如果您有的话),在这种情况下,您可能希望释放正在工作的 space(或允许它被清理如果您使用 VLA,则自动执行)。