使用 strtok 时出现分段错误

Segmentation Fault when using strtok

在 main 中使用 char *s 时出现分段错误。如果我使用 char s[100] 或类似的东西,一切都很好。这是为什么?当我根据指令 char *token = strtok(s, delim); 调用 find_short(char *s) 函数时出现 SIGSEGV。这是我的代码:

#include <sys/types.h>
#include <string.h>
#include <limits.h>
#include <stdio.h>

int find_short(char *s)
{
    int min = INT_MAX;
    const char delim[2] = " ";
    char *token = strtok(s, delim);
    while(token != NULL) {
        int len = (int)strlen(token);
        if (min > len)
            min = len;
        token = strtok(NULL, delim);
    }
    return min;
}
int main()
{
    char *s = "lel qwew dasdqew";
    printf("%d",find_short(s));
    return 0;
}

行:

char *s = "lel qwew dasdqew";

在内存中创建一个指向 常量 字符串的指针。
因为该字符串是常量,所以您无法更改其内容。
strtok 函数将尝试通过在标记分隔符位置插入 [=13=] 来修改内容,但会失败,因为无法修改字符串。


将行更改为:

char s[] = "lel qwew dasdqew";

现在使 s 成为您可以自由更改的本地数据数组。 strtok 现在可以工作了,因为它可以更改数组。

你的主要错误是你选择了错误的函数来完成任务。:)

下面我会讲到这个。

对于当前程序,C 中的字符串文字虽然没有常量字符数组类型,但它们是不可变的。任何更改字符串文字的尝试都会导致未定义的行为。并且函数 strtok 更改传递给它的字符串,在子字符串之间插入终止零。

您应该使用字符串函数 strspnstrcspn 而不是函数 strtok。它们不会更改传递的参数。因此,使用这些函数,您还可以处理字符串文字。

这是一个演示程序。

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

size_t find_short( const char *s )
{
    const char *delim= " \t";

    size_t shortest = 0;

    while ( *s )
    {
        s += strspn( s, delim );

        const char *p = s;

        s += strcspn( s, delim );

        size_t n = s - p;

        if ( shortest  == 0 || ( n && n  < shortest ) ) shortest = n;
    }

    return shortest;
}

int main(void) 
{
    const char *s = "lel qwew dasdqew";

    printf( "%zu", find_short( s ) );

    return 0;
}

它的输出是

3