我为一项任务键入了这段代码:
char *tokens[10];
void parse(char* input);
void main(void)
{
char input[] = "Parse this please.";
parse(input);
for(int i = 2; i >= 0; i--) {
printf("%s ", tokens[i]);
}
}
void parse(char* input)
{
int i = 0;
tokens[i] = strtok(input, " ");
while(tokens[i] != NULL) {
i++;
tokens[i] = strtok(NULL, " ");
}
}但是,看着它,我不确定内存分配是如何工作的。据我所知,我没有定义单个字符串的长度,只定义了字符串数组标记中有多少个字符串(10)。我把这个倒过来了吗?如果不是,那么编译器会动态分配每个字符串的长度吗?需要一些澄清。
发布于 2019-03-07 03:30:37
strtok是个坏公民。
首先,它保留了状态,正如您在调用strtok(NULL,...)时隐式使用的那样--该状态存储在标准C库的私有内存中,这意味着只有单线程程序才能使用strtok。请注意,在某些库中有一个称为strtok_r的可重入版本。
另一方面,为了回答你的问题,strtok修改了它的输入。它不会为字符串分配空间;它会在输入字符串中写入NUL字符来代替分隔符,并返回一个指向输入字符串的指针。
您说得对,strtok可以返回10个以上的结果。您应该在代码中检查这一点,这样就不会超出tokens的结尾。一个可靠的程序要么设置一个上限,比如你的10,并检查它,如果超过它就报告一个错误,要么用malloc动态分配tokens数组,如果它变得太大,就realloc它。然后,当你发现内存不足时,就会出现这个错误。
请注意,您还可以在将输入字符串传递给strtok之前,通过strduping解决strtok修改输入字符串的问题。然后,在它和指向它的tokens都超出作用域之后,您必须释放新的字符串。
发布于 2019-03-07 04:19:28
tokens是一个指针数组。
字符串和指针之间的区别,如果经常模糊的话。在某些情况下,字符串更好地被认为是数组,而在另一些情况下则是指针。
不管怎样..。在您的示例中,input是一个数组,tokens是指向input中某个位置的指针数组。
每次调用strtok()时,input中的数据都会发生变化
所以,一步一步
// input[] = "foo bar baz";
tokens[0] = strtok(input, " ");
// input[] = "foo\0bar baz";
// ^-- tokens[0] points here
tokens[1] = strtok(NULL, " ");
// input[] = "foo\0bar\0baz";
// ^-- tokens[1] points here
tokens[2] = strtok(NULL, " ");
// input[] = "foo\0bar\0baz";
// ^-- tokens[2] points here
// next strtok returns NULLhttps://stackoverflow.com/questions/55030606
复制相似问题