使用指针的C语言中strtok函数出现意外错误

3

我只是想了解下面的strtok()函数的工作原理:

#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(){
    char* p="abc,def,ghi,jkl,mno,pqr,stu,vwx,yz";
    char* q=strtok(p, ",");
    printf("%s", q);

    return 0;
}

我尝试运行这段简单的代码,但是一直收到一个奇怪的错误,我完全不理解。这是我一直收到的错误:

screen shot

可能与此无关,但因为我的命令提示符不断退出,我在项目中更改了一些设置并添加了这行代码 Console (/SUBSYSTEM:CONSOLE),然后我首先尝试运行程序而没有进行调试,但程序甚至都没有运行,然后我尝试进行调试,那就是我得到链接中的错误的方式。


这是一个相当复杂的视图,我仍然不明白人们如何习惯在如此复杂的环境中编程。 - yeyo
4个回答

3

与其

char* p="abc,def,ghi,jkl,mno,pqr,stu,vwx,yz";

使用

char p[] = "abc,def,ghi,jkl,mno,pqr,stu,vwx,yz";

因为根据strtok()man page,它可能会修改输入字符串。在您的代码中,字符串文字是只读的。这就是为什么会导致分段错误。
相关引用:
注意使用这些函数时要小心。如果你确实使用它们,请注意:
* 这些函数会修改它们的第一个参数。

好的答案,没有必要涉及太多技术术语。 - yeyo

2

使用函数strtok时,不要使用字符串字面值,因为该函数尝试更改作为参数传递给它的字符串。

任何尝试更改字符串字面值的操作都会导致未定义的行为。

根据C标准(6.4.5字符串字面值)

7未指定这些数组是否不同,只要它们的元素具有适当的值。 如果程序尝试修改此类数组,则行为是未定义的。

更改此定义

char* p="abc,def,ghi,jkl,mno,pqr,stu,vwx,yz";

to

char s[] = "abc,def,ghi,jkl,mno,pqr,stu,vwx,yz";
//...
char* q = strtok( s, "," );

例如,主函数可以如下所示:
int main()
{
    char s[] = "abc,def,ghi,jkl,mno,pqr,stu,vwx,yz";
    char* q = strtok( s, "," );

    while ( q != NULL )
    {
        puts( q );
        strtok( NULL, "," );
    }

    return 0;
}

2

char* p="abc,def,ghi,jkl,mno,pqr,stu,vwx,yz";将只读内存赋给了p。实际上,p的类型应为const char*

尝试以任何方式更改该字符串都会导致未定义行为。因此,在其上使用strtok是非常糟糕的做法。为解决此问题,请使用

char p[]="abc,def,ghi,jkl,mno,pqr,stu,vwx,yz";

这会在栈上分配字符串,并允许对其进行修改。在某些情况下,p衰减 为指针;其中之一是作为 strtok 的参数。


我尝试过这个,但是之后我不能将p作为strtok函数的参数使用。我是否遗漏了什么非常简单的东西? - ernux

2
首先解决错误:Segmentation fault
char *p更改为char p[]
原因是因为strtok()在找到标记字符时会添加字符串分隔符'\0'。 在您的情况下,char* p="abc,def,ghi,jkl,mno,pqr,stu,vwx,yz";存储在程序的只读部分作为字符串文字。
由于您正在尝试修改只读位置,导致Segmentation fault

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接