3

在某些 CGI 代码中,我需要对很少出现的“&”、“<”和“>”字符进行编码。在编码函数中,如果输入字符串中没有这样的字符,我想立即退出。因此,在进入时,我尝试使用它strtok( )来找出答案:

char *
encode_amp_lt_gt ( char *in ) {
  ...
  if ( NULL == strtok( in, "&<>" )) {
    return in;
  }
  ...
}

但是,即使没有任何定界符,也会strtok( )返回指向 的第一个字符的指针in

如果字符串中没有分隔符,我希望它返回 NULL。

我的代码错了,还是我的期望错了?我不想为了消除通常情况而调用 strchr( ) 三次。

谢谢!

4

2 回答 2

4

您可能不想strtok开始,因为它使您无法确定消除了哪个字符(除非您有字符串的备用副本)。

strtok不是一个简单的 API,很容易被误解。

引用手册

 The strtok() and strtok_r() functions return a pointer to the beginning of
 each subsequent token in the string, after replacing the token itself with
 a NUL character.  When no more tokens remain, a null pointer is returned.

您的问题可能意味着您已经陷入算法的默默无闻。假设这个字符串:

char* value = "foo < bar & baz > frob";

第一次打电话strtok

char* ptr = strtok(value, "<>&");

strtok将返回您的value指针,除了它会将字符串修改为:

"foo \0 bar & baz > frob"

您可能会注意到,它将 更改<NUL. 但是,现在,如果你使用value,你会得到,"foo "因为NUL中间有一个。

strtok对with的后续调用NULL将通过字符串进行,直到您到达字符串的末尾,此时您将获得NULL.

char* str = "foo < bar & frob > nicate";
printf("%s\n", strtok(str, "<>&")); // prints "foo "
printf("%s\n", strtok(NULL, "<>&")); // prints " bar "
printf("%s\n", strtok(NULL, "<>&")); // prints " frob "
printf("%s\n", strtok(NULL, "<>&")); // prints " nicate"
assert(strtok(NULL, "<>&") == NULL); // should be true

编写一个strtok无需.strpbrkstrcat

于 2011-06-29T04:45:53.250 回答
3

你想要的功能是strpbrk,不是strtok。更大的问题是——当你替换东西时,返回的字符串是如何分配的,调用函数如何知道它是否应该释放它?

于 2011-06-29T04:43:46.547 回答