在某些CGI代码中,我需要编码很少发生的'&','<'和'>'字符。在编码功能中,如果输入字符串中没有这样的字符,我想立即离开。因此,在参赛作品时,我尝试使用strtok( )
来查找:
char *
encode_amp_lt_gt ( char *in ) {
...
if ( NULL == strtok( in, "&<>" )) {
return in;
}
...
}
但是,即使没有任何分隔符,strtok( )
也会返回指向in
的第一个字符的指针。
如果字符串中没有delims,我希望它返回NULL。
我的代码错了,还是我的期望错了?我不想为了消除通常的情况而三次调用strchr()。
谢谢!
答案 0 :(得分:4)
您可能不希望strtok
开头,因为它无法确定消除了哪个字符(除非您有字符串的备用副本)。
strtok
不是一个简单的API,很容易误解。
引用manpage:
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
对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
替换内容的函数是相当简单的,既可以自己处理辛苦的工作,也可以从strpbrk
和strcat
获得帮助。
答案 1 :(得分:3)
您想要的功能是strpbrk
,而不是strtok
。更大的问题是 - 当你替换东西时,返回的字符串是如何被分配的,以及调用函数如何知道它是否应该释放它?