1

我有一个像这样使用 strtok 的函数

void f1(char *name)
{
...
char *tmp;
tmp = strtok(names, " ,");
while(tmp)
{
...
tmp = strtok(NULL, " ,");
}
...
}

我有一个电话 f1("abc,def");

问题是在第一次调用中 f1 得到 abc,def 而在第二次调用中得到只是 abc

我很困惑..为什么会这样?

4

4 回答 4

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, " ,");
  }
}
于 2010-04-05T20:57:50.813 回答
2

你说:

我有一个电话 f1("abc,def");

该调用是非法的 - strtok 修改了它的第一个参数,并且不允许您修改字符串文字。你得到的是未定义的行为——任何事情都可能发生。你要:

char a[] = "abc,def";
f1( a );
于 2010-04-05T20:56:16.940 回答
1

你真的在传递一个字符串文字吗?

f1("abc,def");

会将指向字符串文字的指针传递给strtok()in f1()- 因为strtok()修改了字符串,并且无法修改字符串文字,因此您将获得未定义的行为(尽管我预计会发生崩溃或错误而不是意外结果)。

于 2010-04-05T20:56:43.510 回答
-1

strtok在它返回的每个标记之后放置一个空终止符。这意味着它破坏了原始字符串:调用它之后,您的字符串将在第一个标记之后终止,从而导致您看到的行为。

要保持原始字符串不变,您需要在调用之前对其进行复制strtok

于 2010-04-05T20:55:11.693 回答