使用 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
更改传递给它的字符串,在子字符串之间插入终止零。
您应该使用字符串函数 strspn
和 strcspn
而不是函数 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
在 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
更改传递给它的字符串,在子字符串之间插入终止零。
您应该使用字符串函数 strspn
和 strcspn
而不是函数 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