strtok 实验 使用细节

头文件<string.h>
char *strtok(char s[], const char *delim);
用于分隔字符串,常用于网络编程中分隔ip地址
分隔完最后一个词后,再次调用会返回NULL(n个词调用n次)

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

int main()
{
   char a[]="123,456,789";
   printf("%d,%d\n",sizeof(a),strlen(a));
   char *b=strtok(a,",");
    printf("%d,%d\n",sizeof(a),strlen(a));
     printf("%d,%d\n",sizeof(b),strlen(b));
     printf("%s\n",a);
     printf("%s\n",b);


     b=strtok(NULL,",");
    printf("%d,%d\n",sizeof(a),strlen(a));
     printf("%d,%d\n",sizeof(b),strlen(b));
     printf("%s\n",a);
     printf("%s\n",b);

	printf("\n");
	
    char c[]="abc,efg,hij";
     printf("%d,%d\n",sizeof(c),strlen(c));
     b=strtok(c,",");
    printf("%d,%d\n",sizeof(c),strlen(c));
     printf("%d,%d\n",sizeof(b),strlen(b));
     printf("%s\n",c);
     printf("%s\n",b);

    b=strtok(NULL,",");
    printf("%d,%d\n",sizeof(c),strlen(c));
     printf("%d,%d\n",sizeof(b),strlen(b));
     printf("%s\n",c);
     printf("%s\n",b);
    return 0;

}


结果:
在这里插入图片描述

通过上面的实验, 可知:

1.当调用strtok时必须把一个目标分隔完成后再分隔下一个,
2.第一次分隔调用 strtok(a,","),之后分隔调用strtok(NULL,",");
3.调用strtok是在原有的字符数组上进行修改,不会减小原字符数组的长度

4.经实验,多个分隔符在一起会被当成一次分隔处理。

结论,对于编程要注意的:

1.应在分隔前检查分隔符是否非法,比如192…168…17…2

int mark=1;
int count=0;
while(*p!='\0')
{
	if(*p==',')	count++;
	else count=0;
	if(count>1)
	mark=0;//有错误
}
if(mark==1)
{ 正常操作}

2.进行分隔时要使用循环一次行进行分隔
例如:

	
 	char a[]="123,456,789";
 	char c[5][10];
    memset(c[0],0,5*10*sizeof(char));
 	int j=0;
 	b=strtok(a,",");
    strcpy(c[j++],b);
    while(b!=NULL)
    {
          b=strtok(NULL,",");
          if(b==NULL)
            break;
          strcpy(c[j++],b);
    }

strtok 和平常的使用的函数似乎不太一样,好像能记住上一次调用他的情况,这是因为strtok中有个静态的指针指向上次分隔时的下一个位置,当第一个参数有值时,使用第一个参数作为待分隔的字符串,而当第一个参数为NULL,则使用内置的静态指针作为 待分隔的字符串。

补充:

在引入异步之后,
当进程在main() 中执行了strtok 后,如果在信号处理中也调用了strtok,则 当对应的信号出现时,进入信号处理函数,然后返回main()中执行,此时,main()中,strtok内置的静态指针和程序原本期望的静态指针就会发生混乱。(还有插入链表的例子,main中插入一个链表节点,插到一半,来了个信号,也要插入节点,也会发生混乱)

这种在处理中断或者捕捉信号中调用特别的函数而导致的错误,就是因为特别的函数是不可重入的,或者叫做线程不安全的。应该禁止在中断或者信号捕捉函数中调用这类函数。

当由于在中断或者信号捕捉函数中调用这类函数出现bug时,bug的复现情况是随机的,当程序正常执行到某个位置,并且在此时收到某种刺激(中断、信号),这个bug才会复现,而这种情况概率很小,所以一旦出现这种bug,解决起来比较费劲

strtok也因此被称为是不安全的。
为了解决strtok 线程不安全这个问题,c标准库的string.h 中又加入了一个相似的线程安全的版本
char *strtok_r()
前两个参数,以及返回值 ,都和strtok相同,不同之处在于,原来的静态指针的值,变成了保存到第三个参数中。用户可以将第三个参数保存起来,每次调用时,将第三个参数当成第一个参数重新传入

使用方法

char buf[20] = "hello world abc cba";
char *a = buf;
char *b = NULL;

while(NULL != (b = strtok_r(a, " ", &a))){
	printf("%s\n",b);
}

输出:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值