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

时间:2016-09-23 15:54:02

标签: c pointers strtok

我正在尝试将一个字符串(例如:“hey there mister”)转换为指向句子中每个单词的双指针。 so:split_string-> | pointer1 | pointer2 | pointer3 |其中pointer1->“嘿”,指针2->“那里”和指针3->“先生”。

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;
}

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

2 个答案:

答案 0 :(得分:1)

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

  • char **nystreng = malloc(strlen(s));是错的。您需要的空间量是字符串将被拆分的数字的char *倍加上一个(对于NULL指针终止符)。

  • 您使用从本地数组*nystreng上运行的strtok()获取的指针填充str。这些指针仅在str的生命周期内有效,该生命周期在函数返回时结束。

  • 您没有为str中的字符串终结符分配空间,并且您没有写一个空格,但是您将它传递给strtok(),就像它是一个终止字符串一样。

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

这里有一个基本问题,就是在分割字符串之前你不知道将会有多少件。然而,您可以通过计算分隔符数量并添加1来获得上限。然后,您可以为许多char指针加上一个指定空间。或者,您可以构建链接列表以在标记时处理碎片,然后在知道有多少碎片后才分配结果数组。

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

char *str = strdup(s);

否则,您需要检查长度,用malloc()分配足够的空间(包括终结符的空间),并将输入字符串复制到分配的空间中,大概是strcpy() 。通常你会想要在之后释放字符串,但如果要返回指向该空间的指针,则不能这样做。

另一方面,您可以考虑返回一个可以单独释放的字符串数组。为此,您必须单独分配每个子字符串(strdup()如果您拥有它将再次成为您的朋友),并且在那种情况下您可能想要释放工作空间(或者如果您使用它,则允许它自动清理)一个VLA)。

答案 1 :(得分:0)

您需要做两件事 -

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

1的额外'\0'。现在,您将str(未以'\0'终止)传递给strtok,这会导致未定义的行为

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