0

我一直认为strtok应该谨慎对待,因为它通过在最后一个令牌位置插入 NULL 来修改其输入字符串。这也由cppreference验证。

但是,在尝试验证来自 cplusplus.com 的示例时,我发现在 32 位 Windows 7 中的 VS2010 中,strtok 实际上并未在原始字符串中插入 NULL。我可以通过将示例中的参数中的 NULL 修改为 str 来确定这一点,并且程序重复循环,将“This”作为令牌传递,这(正如我解释的那样)与传递前一个行为不同指针,正如 cppreference 声称的那样。

另外,我想也许字符串文字的 const-ness 可能有问题,所以我复制了字符串

char str2[] ="- This, a sample string.";
char str[50];
strcpy(str,str2);

并再次运行它,但循环重复了。调试器显示输入字符串没有被修改。

有人可以在这里解释我哪里出错了吗?编辑:我认为这是我对“行为与先前存储的指针作为 str 传递的行为相同”的解释。

谢谢你。

编辑:确切的代码:

/* strtok example */
#include <iostream>
#include <stdio.h>
#include <string.h>

int main ()
{
  char str2[] ="- This, a sample string.";
  char str[50];
  strcpy(str,str2);
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str," ,.-");
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (str, " ,.-");
    printf("%s\n", str);
  }
  std::cin.ignore();
  return 0;
}

代码输出:

Splitting string "- This, a sample string." into tokens:
This
- This
This
- This
This
- This
This
- This
This
- This
This
- This
This
- This

编辑:已解决我应该删除这个垃圾还是让它留下来?哈哈,我不想从不得不处理这个问题的穷人那里拿分

4

2 回答 2

4

我可以通过将示例中的参数中的 NULL 修改为 str 来确定这一点,并且程序反复循环

这样做是因为当您传入str(或非 NULL 指针)时,strtok()会重新开始,所以它只会标记现在是单个标记的内容(一遍又一遍地返回它)。这是将非 NULL 指针传递给strtok().

当您NULL作为第一个参数传入时strtok(),它会告诉它从上次中断的地方继续(它会在某处的静态变量中跟踪该状态,这是 的问题之一strtok())。

于 2012-10-25T19:29:01.397 回答
3

首先,它不是NULL插入到原始字符串中,而是插入一个零字符。虽然我知道这可能是您想说的,但涉及一个众所周知且完全不相关的宏仍然不是一个好主意NULL

其次,如果strtok在原始字符串中插入零个字符失败,它就不会按预期工作。出于这个原因,我坚信你以某种方式误解了你的实验结果。strtok即使在 32 位 Windows 7 下的 VS2010 中也会修改输入字符串。


您发布的代码的输出清楚地表明该字符串已被修改str的原始值为"- This, a sample string."。从循环内部打印的值str只是"- This". 字符串被截断了,因为strtok在后面插入了一个零字符"- This"(更准确地说,,字符被替换\0字符)。

于 2012-10-25T19:23:52.090 回答