strtok调用时出现问题

发布于 2024-08-28 06:49:08 字数 268 浏览 8 评论 0原文

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

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

我有一个调用 f1("abc,def");

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

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

I have a function using strtok like this

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

And i have a call f1("abc,def");

Problem is that in first call f1 gets abc,def
and in 2nd call gets just abc

I am confused.. Why is this so?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦冥 2024-09-04 06:49:08

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, " ,");
  }
}

strtok() modifies its input string by overwriting the delimiters with a 0; so, assuming your code looks something like this:

char parm[] = "abc,def";

f1(parm);
f1(parm);

after the first call to f1, the ',' character is overwritten with a 0, which is a string terminator, so the second call only sees "abc" as the string.

Note that because strtok() modifies its input, you do not want to pass it a string literal as an argument; attempting to modify the contents of a string literal invokes undefined behavior.

The safe thing to do is to create a local string within f1 and copy the contents of names to it, then pass that local string to strtok(). The following should work with 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, " ,");
  }
}
烟花肆意 2024-09-04 06:49:08

你说:

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

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

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

You say:

And i have a call f1("abc,def");

That call is illegal - strtok modifies its first parameter and you are not allowed to modify string literals. What you get is undefined behaviour - anything could happen. You want:

char a[] = "abc,def";
f1( a );
秋凉 2024-09-04 06:49:08

您真的传递了字符串文字吗?

f1("abc,def");

会将指向字符串文字的指针传递给 f1() 中的 strtok() - 因为 strtok() 修改字符串,并且字符串文字无法修改,因此您将得到未定义的行为(尽管我期望崩溃或故障而不是意外结果)。

Are you truly passing in a string literal?

f1("abc,def");

will pass a pointer to the string literal to the strtok() in f1() - since strtok() modifies the string, and a string literal can't be modified, so you'll get undefined behavior (though I would expect a crash or fault instead of unexpected results).

那片花海 2024-09-04 06:49:08

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

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

strtok puts a null terminator after each token it returns. This means that it destroys the original string: After calling it, your string will be terminated after the first token, resulting in the behavior you see.

To keep the original string unchanged, you will need to make a copy of it before calling strtok.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文