关于strtok()函数的研究

发现了一个奇怪的函数逻辑:

#include <string.h>
#include <stdio.h>
int main () {
   char str[80] = "This is - www.runoob.com - website";
   const char s[2] = "-";
   char *token;
 
   /* 获取第一个子字符串 */
   token = strtok(str, s);
   /* 继续获取其他的子字符串 */
   while( token != NULL ) {
      printf( "%s\n", token );   
      token = strtok(NULL, s);
   }
   return(0);
}

运行结果如下:
在这里插入图片描述
疑问在于,为什么strtok()这个函数在获取第一个子字符串之后需要设置一下strtok(NULL, s)呢?
百思不得其解的去查了查这个函数的原型以及解释:

strtok()字符串分割函数

一、函数原型

char *strtok(char s[], const char *delim)

二、参数及返回值说明

名称作用
s[]要分解的字符串
*delim分割字符,如果传入的是字符串,则字符串包含的每个字符均为分隔符
返回值返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针

三、思考与实践

关于在函数的参数和返回值里没获得解决疑问的关键,我决定自己动手试一试。先来看看在截取了第一次子字符串之后,原字符串变成什么了

#include <string.h>
#include <stdio.h>
 
int main () {
   char str[80] = "This is - www.runoob.com - website";
   const char s[2] = "-";
   char *token;
   
   /* 获取第一个子字符串 */
   token = strtok(str, s);
   
   printf("%s\n",token);
   printf("%s\n",str);
   
   return(0);
}

神奇的事情发生了,原字符串剩下的部分去哪儿了?:
在这里插入图片描述

四、查阅资料

查询资料后发现strtok函数执行过程有这样几个重点

  • 当strtok()在参数s的字符串中发现参数delim中包含的分割字符时,则会将该字符改为\0 字符。
  • 在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。
  • 每次调用成功则返回指向被分割出片段的指针
  • 使用该函数进行字符串分割会破坏被分解字符串的完整
  • 第一次分割之后,原字符串变为了分割完成之后的第一个字符串,剩余的字符串存储在一个静态变量中,因此多线程同时访问该静态变量时,则会出现错误。

五、扩展

为了保证数据的安全性,人们想出了很多的办法,在此分割函数的基础上构建了很多新的函数。例如;

  • strtok_s
    strtok_s是windows下的一个分割字符串安全函数,函数原型:
    char *strtok_s( char *strToken, const char *strDelimit, char **buf);
    该函数将剩余的字符串存储在buf变量中,而不是静态变量中,从而保证了安全性。

  • strtok_r
    strtok_r是linux下的一个分割字符串安全函数,函数原型:
    char *strtok_r(char *str, const char *delim, char **saveptr);
    该函数将剩余的字符串存储在saveptr变量中,保证了安全性。

分享就到这里,感谢观看。

“写程序,不比其它的学科,动手才是硬道理。” ——绝影Hamber
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值