strtok 标记化的奇怪行为

strtok weird behavior on tokenization

下面的代码给出了意外的行为。

#include <stdio.h>
#include <string.h>

int main()
{
    
    char s[] = "hello $";
    char *t;
    t = strtok(s, "$$");
    printf("%s", t);

    return 0;
}

为什么这个输出 hello 而不是 hello $

来自C标准(7.23.5.8的strtok函数)

2 A sequence of calls to the strtok function breaks the string pointed to by s1 into a sequence of tokens, each of which is delimited by a character from the string pointed to by s2

在本次通话中

t = strtok(s, "$$");

参数 s2 设置为具有两个相同的分隔符。所以调用相当于

t = strtok(s, "$");

如果您需要在字符串中查找子字符串“$$”,您可以使用标准 C 字符串函数 strstr。例如

#include <stdio.h>
#include <string.h>

int main(void) 
{
    char s[] = "hello $";
    
    char *p = strstr( s, "$$" );
    
    if ( p ) *p = '[=12=]';
    
    puts( s );
    
    return 0;
}

在您写的评论中:

so how should I split by a string?

据我所知,没有执行此操作的标准方法(没有预定义的库函数)。

您可以使用 strstr 编写自己的字符串拆分循环。这是一种方法:

#include <stdio.h>
#include <string.h>

int main()
{
    char s[] = "hello$$this$$is$$a$$test";
    char *sep = "$$";
    char *p = s;
    char *p2;
    int i = 1;
    do {
        p2 = strstr(p, sep);
        if(p2 != NULL) *p2 = '[=10=]';
        printf("%d: %s\n", i++, p);
        if(p2 != NULL) p = p2 + strlen(sep);
    } while(p2 != NULL);
}

这可以改进,但它有效,应该可以帮助您入门。