C/C++ 字符串分割: strtok 与 strsep 函数说明
函数原型:
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)得到各部分子串。
作用:
分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。
说明:
strtok()用来将字符串分割成一个个片段。参数s指向欲分割的字符串,参数delim则为分割字符串,当strtok()在参数s的字符串中发现到参数delim的分割字符时则会将该字符改为\0 字符。在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。每次调用成功则返回下一个分割后的字符串指针。
返回值:
从s开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。
所有delim中包含的字符都会被滤掉,并将被滤掉的地方设为一处分割的节点。(如下面的例子,可修改 seps里面的数据,然后看输出结果)
#include <string.h>
#include <stdio.h>
char string[] ="A string\tof ,,tokens\nand some more tokens";
char seps[] =" ,\t\n";
char *token;
int main( void )
{
printf( "%s\n\nTokens:\n", string );
/* Establish string and get the first token: */
token = strtok( string, seps );
while( token != NULL )
{
/* While there are tokens in "string" */
printf( " %s\n", token );
/* Get next token: */
token = strtok( NULL, seps );
}
return ;
}
总结:
strtok内部记录上次调用字符串的位置,所以不支持多线程,可重入版本为strtok_r,有兴趣的可以研究一下。它适用于分割关键字在字符串之间是“单独”或是 “连续“在一起的情况。
strsep:
#include <string.h>
#include <stdio.h>
char string[] ="A string\tof ,,tokens\nand some more tokens";
char seps[] =" ,\t\n";
char *token, *s;
int main( void )
{
printf( "%s\n\nTokens:\n", string );
/* Establish string and get the first token: */
s=string;
token = strsep( &s, seps );
while( token != NULL )
{
/* While there are tokens in "string" */
printf( " %s\n", token );
/* Get next token: */
token = strsep( &s, seps );
}
return ;
}
为什么用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的例子中有多个换行的原因。
改进后的代码:
效果:
其中, 字符‘\0’ 的 10进制数为0 , 宏定义为 NULL 。
下面的说明摘自于最新的Linux内核2.6.29,说明了strtok()已经不再使用,由速度更快的strsep()代替。
/** linux/lib/string.c** Copyright (C) 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
*/
总结:
strsep返回值为分割后的开始字符串,并将函数的第一个参数指针指向分割后的剩余字符串。它适用于分割关键字在两个字符串之间只严格出现一次的情况。
PS:
因为函数内部会修改原字符串变量,所以传入的参数不能是不可变字符串(即文字常量区)。
如 char *tokenremain ="abcdefghij"//编译时为文字常量,不可修改。
strtok(tokenremain,"cde");
strsep(&tokenremain,"cde");
编译通过,运行时会报段错误。
C/C++ 字符串分割: strtok 与 strsep 函数说明的更多相关文章
- 第11.22节 Python 中re模块的字符串分割器:split函数
一. 引言 在<第11.2节 Python 正则表达式支持函数概览>介绍了re模块的主要函数,在<第11.3节 Python正则表达式搜索支持函数search.match.fullm ...
- C语言strtok()函数:字符串分割
头文件:#include <string.h> 定义函数:char * strtok(char *s, const char *delim); 函数说明:strtok()用来将字符串分割成 ...
- strtok、strtok_s、strtok_r 字符串分割函数
1.strtok函数 函数原型:char * strtok (char *str, const char * delimiters); 参数:str,待分割的字符串(c-string):delimit ...
- 【Teradata SQL】字符串分割函数STRTOK和STRTOK_SPLIT_TO_TABLE
STRTOK函数: 按照指定分隔符,将字符串分割成多个部分,返回指定部分字符串. 参数说明: (1)instring:字符串或字符串表达式. (2)delimiter:分隔符列表,字符串每个字符都会做 ...
- (十六)strtok、strtok_s、strtok_r 字符串分割函数
1.strtok函数 函数原型:char * strtok (char *str, const char * delimiters); 参数:str,待分割的字符串(c-string):delimit ...
- C语言中的字符串分割函数
char *strtok(char *s, const char *delim); 分解字符串为一组字符串.s为要分解的字符串,delim为分隔符字符串. 从s开头开始的一个个被分割的串.当没有被分割 ...
- c语言字符串分割函数(转)
源:C语言实现split以某个字符分割一个字符串 void split(char *src, const char *separator, char **dest, int *num) { /* sr ...
- 从标准输入读取一行数组并保存(用的是字符串分割函数strtok_s() )
首先介绍字符串分割函数: char *strtok_s( char *strToken, //字符串包含一个标记或一个以上的标记. const char *strDelimit, //分隔符的设置 c ...
- php学习零散笔记—字符串分割、fetch函数和单双引号。
1 字符串分割——split()函数和preg_split()函数 split — 用正则表达式将字符串分割到数组中——貌似PHP5.3以上已不赞成使用 array split ( string $p ...
随机推荐
- MongoDB(课时30 $group)
3.7.5.聚合框架(核心) MapReduce功能强大,但是它的复杂度和功能一样强大,那么我们需要MapReduce的功能,使用聚合框架中的聚合函数:aggregate(). 3.7.5.1.gro ...
- Flutter学习笔记(二)
*.assets 当引用图片的时候,需要在pubspec.yaml的文件中的flutter下添加assets,类似于下面的样子: image.png 这里需要注意的是文件里的assets只要一个缩进即 ...
- RabbitMQ入门_15_访问控制
参考资料:https://www.rabbitmq.com/access-control.html A. 核心概念 Virtual Host:虚拟主机为 RabbitMQ 中的资源提供了逻辑分组与隔离 ...
- Codeforces 680D - Bear and Tower of Cubes
680D - Bear and Tower of Cubes 思路:dfs+贪心,设剩余的体积为res,存在a,使得a3 ≤ res,每次取边长为a的立方体或者边长为a-1的立方体(这时体积上限变成a ...
- 8天掌握EF的Code First开发
C#高级知识点&(ABP框架理论学习高级篇)——白金版 http://www.cnblogs.com/farb/p/ABPAdvancedTheoryContent.html
- 在浏览器外打开PDF文档
One function you might find annoying with PDFs and PDF Readers is that when you click on a link to a ...
- 关于C和C++
最开始学的就是C和C++,但只是学过,根本就不知道怎么使用. 后来接触了Python和Perl才知道怎么将编程应用于实际需求当中,读取文件,存放到数据结构,处理,输出. 但脚本语言有其固有的缺点,不能 ...
- Spring Boot 系统要求
Spring Boot 2.1.0.RELEASE 方需要 Java 8 or 9 的支持和 Spring Framework 5.1.2.RELEASE 以上的版本. 明确的构建工具的支持,请参考下 ...
- java MongoDB查询(一)简单查询
前言 MongoDB的java驱动提供了查询的功能,查询条件也是bson对象,这篇就看下怎么进行简单的数据查询 1.数据结构 集合:firstCollection 数据内容: { "_id& ...
- P4721 【模板】分治 FFT
其实是分治ntt,因为fft会爆精度,真*裸题 分治过程和fft的一模一样,主要就是ntt精度高,用原根来代替fft中的\(w_n^k\) 1.定义:设m>1,(a,m)==1,满足\(a^r= ...