我有一个像这样使用strtok的功能
void f1(char *name)
{
...
char *tmp;
tmp = strtok(names, " ,");
while(tmp)
{
...
tmp = strtok(NULL, " ,");
}
...
}
我有一个电话f1(“abc,def”);
问题是在第一次调用时f1得到abc,def 而在第二次通话中只获得abc
我很困惑..为什么会这样?
答案 0 :(得分:4)
strtok()
通过用0覆盖分隔符来修改其输入字符串;所以,假设你的代码看起来像这样:
char parm[] = "abc,def";
f1(parm);
f1(parm);
在第一次调用f1之后,','字符被0覆盖,这是一个字符串终止符,因此第二个调用只将“abc”视为字符串。
请注意,因为strtok()
修改了它的输入,所以您不希望将字符串文字作为参数传递给它;尝试修改字符串文字的内容会调用未定义的行为。
安全的做法是在f1中创建一个本地字符串并将名称的内容复制到它,然后将该本地字符串传递给strtok()
。以下内容适用于C99:
void f1(char *name)
{
size_t len = strlen(name);
char localstr[len+1];
char *tmp;
strcpy(localstr, name);
tmp = strtok(localstr, " ,");
while(tmp)
{
...
tmp = strtok(NULL, " ,");
}
}
答案 1 :(得分:1)
你说:
我有一个电话f1(“abc,def”);
该调用是非法的 - strtok修改其第一个参数,并且不允许修改字符串文字。你得到的是未定义的行为 - 任何事情都可能发生。你想要:
char a[] = "abc,def";
f1( a );
答案 2 :(得分:1)
你真的传递了一个字符串文字吗?
f1("abc,def");
会将指向字符串文字的指针传递给strtok()
中的f1()
- 因为strtok()
修改了字符串,并且字符串文字无法修改,所以你会得到未定义的行为(虽然我希望崩溃或错误而不是意外的结果)。
答案 3 :(得分:0)
strtok
在返回的每个标记后放置一个空终止符。这意味着它会破坏原始字符串:在调用它之后,您的字符串将在第一个令牌后终止,从而导致您看到的行为。
要保持原始字符串不变,您需要在调用strtok
之前复制它。