我正在尝试将一个字符串(例如:“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;
}
我的问题是,为什么这不起作用?
答案 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终止符的空格)。