strtok段错误

strtok函数分解字符串为一组标记串,原型为: extern char *strtok(char *s, char *delim); s 为要分解的字符串, delim 为分隔符字符串。首次调用时, s 必须指向要分解的字符串,随后调用要把 s 设成 NULL strtok s 中查找包含在 delim 中的字符 并用 NULL(‘/0’) 来替换,直到找遍整 个字符串。返回指向目前找到的最后一个标记串,当没有标记串时则返回空字符 NULL [1]

       看下面的一 段程序:

#include<string.h>

 

int main()

{

       char *s="Golden Global View";

       char *d=" ";

       char *p;

 

       p=strtok(s,d);

       while(p)

       {

              printf("%s/n",p);

              p=strtok(NULL,d);

       }

 

       return 1;

}

编译没有问题,但运行时会出现 Segmentation fault 的错误。

       有些人就会 百思不得其解,认为是 strtok 的问题,其 实不然。如果将 s 的定义由 char *s 改成 char s[] char s[20] ,则运行时就不会出现段错误而是想要的结果。可见问题不是 strtok 而是字符串常量的问题。看 strtok 的原型, s 不是 const 的,说明在 strtok 里会修改 s 的值,而如果定义 char *s="Golden Global View" ,则 s 指向只读区域不能修改。

       可以看下面 的程序:

       #include<string.h>

 

int main()

{

       char *s=(char *)malloc(sizeof(char)*10);

       s="abcdef";

       *(s+1)='g';

}

运行时会出现段错误。

       下面的程序:

       #include<string.h>

 

int main()

{

       char *s=(char *)malloc(sizeof(char)*10);

       strcpy(s,"abcdef");

       *(s+1)='g';

}

则会正确运行。

       出现这些不同的结果,究其原因,是“非常量指针指向了常量字符串”。 ”abcdef” 本身是一个常量字符串,系统把它放在了只读权限的内存空间,用可读写的指针指向这块区域本身就是错误的(逻辑上),而对只读内存区域进行写操作 则造成了实际的错误 [2] char s[]=”abc” 则不然,首先声明了一个字符数组,然后将数组的大小定义成刚好能存下 ”abc” 字 符串,并且将 ”abc” 存入该数组,这时数组存放在数据区并且已经在数据区分配了相应的空间。其实如果想改写指针指向的空 间,就要确保指针指向可写的空间,想强制改写只读区域的内容是不鼓励的而且是另一个问题,再此不讨论。

还有一个规则就是,非常 量指针可以隐式转换成常量指针,而反之则需要显示转换。如:

char a[1 strtok函数分解字符串为一组标记串,原型为: extern char *strtok(char *s, char *delim); s 为要分解的字符串, delim 为分隔符字符串。首次调用时, s 必须指向要分解的字符串,随后调用要把 s 设成 NULL strtok s 中查找包含在 delim 中的字符 并用 NULL(‘/0’) 来替换,直到找遍整 个字符串。返回指向目前找到的最后一个标记串,当没有标记串时则返回空字符 NULL [1]

       看下面的一 段程序:

#include<string.h>

 

int main()

{

       char *s="Golden Global View";

       char *d=" ";

       char *p;

 

       p=strtok(s,d);

       while(p)

       {

              printf("%s/n",p);

              p=strtok(NULL,d);

       }

 

       return 1;

}

编译没有问题,但运行时会出现 Segmentation fault 的错误。

       有些人就会 百思不得其解,认为是 strtok 的问题,其 实不然。如果将 s 的定义由 char *s 改成 char s[] char s[20] ,则运行时就不会出现段错误而是想要的结果。可见问题不是 strtok 而是字符串常量的问题。看 strtok 的原型, s 不是 const 的,说明在 strtok 里会修改 s 的值,而如果定义 char *s="Golden Global View" ,则 s 指向只读区域不能修改。

       可以看下面 的程序:

       #include<string.h>

 

int main()

{

       char *s=(char *)malloc(sizeof(char)*10);

       s="abcdef";

       *(s+1)='g';

}

运行时会出现段错误。

       下面的程序:

       #include<string.h>

 

int main()

{

       char *s=(char *)malloc(sizeof(char)*10);

       strcpy(s,"abcdef");

       *(s+1)='g';

}

则会正确运行。

       出现这些不同的结果,究其原因,是“非常量指针指向了常量字符串”。 ”abcdef” 本身是一个常量字符串,系统把它放在了只读权限的内存空间,用可读写的指针指向这块区域本身就是错误的(逻辑上),而对只读内存区域进行写操作 则造成了实际的错误 [2] char s[]=”abc” 则不然,首先声明了一个字符数组,然后将数组的大小定义成刚好能存下 ”abc” 字 符串,并且将 ”abc” 存入该数组,这时数组存放在数据区并且已经在数据区分配了相应的空间。其实如果想改写指针指向的空 间,就要确保指针指向可写的空间,想强制改写只读区域的内容是不鼓励的而且是另一个问题,再此不讨论。

还有一个规则就是,非常 量指针可以隐式转换成常量指针,而反之则需要显示转换。如:

char a[10];

const char *p=a; 这是没有问题的。反过来:

const char *p=”abc”;

char *a=p; 这是不允许的,需要进行强制转换: char *a=(char *)p[3]

0];

const char *p=a; 这是没有问题的。反过来:

const char *p=”abc”;

char *a=p; 这是不允许的,需要进行强制转换: char *a=(char *)p[3]

 

原文 http://blog.chinaunix.net/u3/104318/showart_2059498.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值