strtok给出分段错误

为什么下面的代码给出了Seg。 最后一行出错?

char* m=ReadName(); printf("\nRead String %s\n",m); // Writes OK char* token; token=strtok(m,'-'); 

如上所述,读取字符串打印没有问题,但为什么不能拆分为令牌?

strtok修改了它的第一个参数,因此它应该是可修改的。

也许ReadName()返回一个指向只读char数组的指针。您可以向我们展示您的ReadName()函数。

如果这是seg-faullt的原因,您可以在使用strdup函数将其传递给strtok之前创建char数组的副本,如:

 char *copy = strdup(m); token = strtok(copy,'-'); .... .... free(copy); // free the copy once you are done using it. 

token=strtok(m,'-'); 应生成编译器警告,因为strtok()的第二个参数是一个指向多个分隔符的const char * ,而不是一个char分隔符:

 char *strtok(char *str, const char *delim); 

'-'的ASCII代码是0x2D,因此将其作为strtok()的第二个参数传递将导致strtok()取消引用地址0x0000002D,这将导致大多数现代操作系统上的段错误或访问冲突。 要解决此问题,请使用字符串文字而不是字符文字: token=strtok(m,"-");

还有一个问题是如何分配ReadName()的返回值,其他人已经在他们的答案中解决了这个问题。

如果不知道m指向什么,就不可能确定。 但最可能的原因是m指的是只读内存。 所以你可以打印出来,但你不能写信给它。

strtok写入字符串,所以它是错误的,但printf只读取它,所以它不是。

试试这个

 char* m=ReadName(); printf("\nRead String %s\n",m); // Writes OK char temp = m[0]; m[0] = temp; // I'll bet you segfault here. 

它可能是因为ReadName()返回字符串。 因此,赋值使得m const char *,因此,您不能更改其任何值(修改字符串)。 因此,当’strtok’尝试修改’m’时,会出现Segmentation Fault

补救:

 char *m = malloc(sizeof(char)*MAX); strcpy(m, ReadName()); 

要么

 char *m = strdup(ReadName()); 

下面的代码取自C的BSD许可字符串处理库,称为zString 。

https://github.com/fnoyanisi/zString

查看函数的实现,您可以看到strtok() (或者在本例中为zstring_strtok() )依赖于static *char来保留分隔符的最后位置并实际修改原始字符串。

 char *zstring_strtok(char *str, const char *delim) { static char *static_str=0; /* var to store last address */ int index=0, strlength=0; /* integers for indexes */ int found = 0; /* check if delim is found */ /* delimiter cannot be NULL * if no more char left, return NULL as well */ if (delim==0 || (str == 0 && static_str == 0)) return 0; if (str == 0) str = static_str; /* get length of string */ while(str[strlength]) strlength++; /* find the first occurance of delim */ for (index=0;index 

这篇文章很好地解释了char s[]char *s之间的差异。 所以,

 char s[]="Test to pass strtok()"; /* this can be passed to strtok() */ char *m="Test to pass strtok()"; /* passing this will result in SIGSEGV */