strtok函数c元素考虑的问题

Leo*_*rdo 1 c split substring c-strings

当我尝试用分隔符分割字符串时,该strtok函数不考虑空字符串,我想知道如何修复它。例如,就我而言,我必须拆分字符串,例如"a-b-c". 当我尝试拆分字符串时"a--b-c",结果应该是,,,, "a"(注意空字符串)。但如果我在调用函数后打印每个元素的结果,它只考虑、和。为什么会发生这种情况?我该如何解决?"""b""c""a""b""c"

    char str[] = "a--b-c";
    char *delim = "-";
    char *token;

    token = strtok(str, delim);

    while (token != NULL) {
        printf("element is: =====%s===== \n ", token);
        token = strtok(NULL, delim);
    }
Run Code Online (Sandbox Code Playgroud)

打印的元素应该是 4 ( a, 空字符串 , b, c) 但使用此代码,它只有 3 ( a, b, c)。

Tob*_*ght 6

根据C标准,第一个动作strtok()

在 指向的字符串中搜索 包含在 指向的当前分隔符字符串中的s1第一个字符。s2

如果您想要不同的行为,您需要编写自己的函数来执行您想要的操作。


Vla*_*cow 5

该函数strtok搜索当前分隔符字符串中不包含的第一个字符。因此相邻的分隔符会被跳过。

该函数还会更改源字符串。

您可以使用另一个字符串函数来代替使用strtok,例如strcspn

这是一个演示程序。

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

int main( void )
{
    char str[] = "a--b-c";
    const char *delim = "-";

    for (char *p = str; *p != '\0'; )
    {
        size_t n = strcspn( p, delim );

        printf( "\"%.*s\"\n", ( int )n, p );

        if ( *( p += n ) != '\0') ++p;
    }
}
Run Code Online (Sandbox Code Playgroud)

程序输出是

"a"
""
"b"
"c"
Run Code Online (Sandbox Code Playgroud)

如果对于这样的字符串,"-"您需要输出两个子字符串,例如

""
""
Run Code Online (Sandbox Code Playgroud)

或者对于像这样的字符串,"a--b-c-"您需要输出

"a"
""
"b"
"c"
""
Run Code Online (Sandbox Code Playgroud)

那么在程序中进行以下小改动就足够了

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

int main( void )
{
    char str[] = "a--b-c-";
    const char *delim = "-";

    for (char *p = str; *p != '\0'; )
    {
        size_t n = strcspn( p, delim );

        printf( "\"%.*s\"\n", ( int )n, p );

        if (*( p += n ) != '\0')
        {
            if (*++p == '\0')
            {
                printf( "\"%s\"\n", p );
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

本例中程序的输出是

"a"
""
"b"
"c"
""
Run Code Online (Sandbox Code Playgroud)

对于指针指向的每个获取的子字符串p和长度,n您可以定义一个可变长度字符数组或动态分配一个字符数组,然后在需要时复制数组中的子字符串。例如

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

int main( void )
{
    char str[] = "a--b-c";
    const char *delim = "-";

    for (char *p = str; *p != '\0'; )
    {
        size_t n = strcspn( p, delim );

        char substr[n + 1];

        memcpy( substr, p, n );
        substr[n] = '\0';
             
        printf( "\"%s\"\n", substr );

        if ( *( p += n ) != '\0') ++p;
    }
}
Run Code Online (Sandbox Code Playgroud)