首页天道酬勤strtok函数用法例子,strtok

strtok函数用法例子,strtok

admin 08-28 16:45 385次浏览

以下来自:https://blog.csdn.net/yafeng_jiang/article/details/7109285
函数原型
char *strtok(char *s, const char *delim);
char *strsep(char **s, const char *delim);

功能:strtok和strsep两个函数的功能都是用来分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。

返回值:从s开头开始的一个个子串,当没有分割的子串时返回NULL。

相同点:两者都会改变源字符串,想要避免,可以使用strdupa(由allocate函数实现)或strdup(由malloc函数实现)。

strtok函数第一次调用时会把s字符串中所有在delim中出现的字符替换为NULL。然后通过依次调用strtok(NULL, delim)得到各部分子串。

测试代码:

#include <stdio.h>#include <string.h> int main(void) {char s[] = "hello, world! welcome to china!";char delim[] = " ,!"; char *token;for(token = strtok(s, delim); token != NULL; token = strtok(NULL, delim)) {printf(token);printf("+");}printf("\n");return 0;}

输出结果为:hello+world+welcome+to+china

对于strsep有如下例子:

#include <stdio.h>#include <string.h> int main(void) {char source[] = "hello, world! welcome to china!";char delim[] = " ,!"; char *s = strdup(source);char *token;for(token = strsep(&s, delim); token != NULL; token = strsep(&s, delim)) {printf(token);printf("+");}printf("\n");return 0;}

输出结果为:hello++world++welcome+to+china++
ps:strdup函数: 将字符串拷贝到新建的位置处
strdup()在内部调用了malloc()为变量分配内存,不需要使用返回的字符串时,需要用free()释放相应的内存空间,否则会造成内存泄漏。
参考:https://baike.baidu.com/item/strdup/5522525?fr=aladdin

为什么用strtok时子串中间只有一个“+”,而strsep却有多个"+"呢?文档中有如下的解释:
One difference between strsep and strtok_r is that if the input string contains more
than one character from delimiter in a row strsep returns an empty string for each
pair of characters from delimiter. This means that a program normally should test
for strsep returning an empty string before processing it.

大意是:如果输入的串的有连续的多个字符属于delim,(此例source中的逗号+空格,感叹号+空格等就是这种情况),strtok会返回NULL,而strsep会返回空串""。因而我们如果想用strsep函数分割字符串必须进行返回值是否是空串的判断。这也就解释了strsep的例子中有多个"+"的原因。

我们在自己的程序中最好尽量避免使用strtok,转而使用strsep。

下面的说明摘自于最新的Linux内核2.6.29,说明了strtok()已经不再使用,由速度更快的strsep()代替。

/** linux/lib/string.c** Copyright © 1991, 1992 Linus Torvalds*/

/** stupid library routines… The optimized versions should generally be found

as inline code in <asm-xx/string.h>

These are buggy as well…

Fri Jun 25 1999, Ingo Oeser ioe@informatik.tu-chemnitz.de Added strsep() which will replace strtok() soon (because strsep() is

reentrant and should be faster). Use only strsep() in new code, please.

** * Sat Feb 09 2002, Jason Thomas jason@topic.com.au,

Matthew Hawkins matt@mh.dropbear.id.au

Kissed strtok() goodbye

*/

以下来自百度百科:https://baike.baidu.com/item/strsep/5613872?fr=aladdin
分解字符串为一组字符串。从stringp指向的位置起向后扫描,遇到delim指向的字符串中的字符后,将此字符替换为NULL,返回stringp指向的地址。它适用于分割“关键字”在两个字符串之间只“严格出现一次”的情况。 [1] 如果“关键字”在字符串之间连续出现,可使用如下技巧解决:
char str[] = “abcdefg”;
  char *p = str;
  char *key_point;
  while§
  {
  while ( key_point = strsep(&p,“cd”))//关键字为c或d,它们连续出现了
  {
  //函数遇到c时,key_point指向c返回,遇到d时key_point指向d返回(注意此时d已经被改写 为’\0’了)
  if (*key_point == 0)
  continue;//遇到连续的关键字,返回一个指向\0的指针,继续往后找就是
  else
  break;//分割出一个正常的字符串,快去打印吧!
  }
  printf("%s\n",key_point);
  }

以下来自:https://www.cnblogs.com/longzhao1234/archive/2012/05/31/2528317.html
总结:
strtok内部记录上次调用字符串的位置,所以不支持多线程,可重入版本为strtok_r,有兴趣的可以研究一下。它适用于分割关键字在字符串之间是“单独”或是 “连续“在一起的情况。

strsep返回值为分割后的开始字符串,并将函数的第一个参数指针指向分割后的剩余字符串。它适用于分割关键字在两个字符串之间只严格出现一次的情况。

通过阅读函数实现源码,可以灵活运用这两个函数,为自己所用!

PS
因为函数内部会修改原字符串变量,所以传入的参数不能是不可变字符串(即文字常量区)。

如 char *tokenremain =“abcdefghij”//编译时为文字常量,不可修改。

strtok(tokenremain,“cde”);

strsep(&tokenremain,“cde”);

编译通过,运行时会报段错误。

PS
找个库函数源码的在线查询网站真不容易,先找到了这个
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/?cvsroot=glibc

之后,发现了经常去找软件的oschina有源码库,真是踏破铁鞋无觅处,得来全不费工夫!

http://www.oschina.net/code/explore/glibc-2.9/string/strtok.c

vue2和vue3的区别有哪些怎么用Vue指令实现大屏元素分辨率适配Comparetrue/falsearraywithotherarraynslookup命令如何使用-linux运维CentOS 7 安装配置 ohmyzsh阿诺德渲染器gpu需要学习么?win7电脑文件夹如何加密
c语言分割字符串为字符,一串字符以逗号分割 linux按空格分割字符串,mysql字符串按字符分割
相关内容