C 呼叫中的strtok问题

C 呼叫中的strtok问题,c,strtok,C,Strtok,我有一个像这样使用strtok的函数 void f1(char *name) { ... char *tmp; tmp = strtok(names, " ,"); while(tmp) { ... tmp = strtok(NULL, " ,"); } ... } 我有个电话叫f1abc,def 问题是,在第一次调用中,f1得到abc,def 在第二次通话中,只有abc 我很困惑。。为什么会这样呢?strtok在返回的每个令牌后都放置一个空终止符。这意味着它将破坏原始字符串:调用它后,字符串

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

void f1(char *name)
{
...
char *tmp;
tmp = strtok(names, " ,");
while(tmp)
{
...
tmp = strtok(NULL, " ,");
}
...
}
我有个电话叫f1abc,def

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

我很困惑。。为什么会这样呢?

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

要保持原始字符串不变,您需要在调用strtok之前复制它。

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

要保持原始字符串不变,您需要在调用strtok之前复制它。

您说:

我有个电话叫f1abc,def

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

char a[] = "abc,def";
f1( a );
你说:

我有个电话叫f1abc,def

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

char a[] = "abc,def";
f1( a );

您真的在传递字符串文本吗

f1("abc,def");

将向f1中的strtok传递一个指向字符串文字的指针-因为strtok修改字符串,并且不能修改字符串文字,所以您将得到未定义的行为,尽管我预计会出现崩溃或错误,而不是意外的结果。

您真的要传递字符串文字吗

f1("abc,def");
将向f1中的strtok传递一个指向字符串文本的指针-因为strtok修改字符串,并且不能修改字符串文本,所以您将获得未定义的行为,尽管我预期会出现崩溃或错误,而不是意外的结果。

strtok通过用0覆盖分隔符来修改其输入字符串;因此,假设您的代码如下所示:

char parm[] = "abc,def";

f1(parm);
f1(parm);
在第一次调用f1之后,“,”字符将被0覆盖,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, " ,");
  }
}
strtok通过用0覆盖分隔符来修改其输入字符串;因此,假设您的代码如下所示:

char parm[] = "abc,def";

f1(parm);
f1(parm);
在第一次调用f1之后,“,”字符将被0覆盖,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, " ,");
  }
}

这是真的密码吗?只有函数中有名称,并且名称作为参数。strtok修改传递给它的字符串。如果你不想这样,你需要保存一份副本。因为strtok修改字符串,用只读字符串strtokabc,def调用它;没有定义。如果可以,发布真实代码。这是真实代码吗?只有函数中有名称,并且名称作为参数。strtok修改传递给它的字符串。如果你不想这样,你需要保存一份副本。因为strtok修改字符串,用只读字符串strtokabc,def调用它;没有定义。如果可以,发布真实代码。