CC++字符串分割: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 );
}
return0;
}
总结:
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 );
}
return0;
}
为什么⽤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.au>,
* Matthew Hawkins <matt@mh.dropbear.id.au>
* - Kissed strtok() goodbye
*/
总结:
strsep返回值为分割后的开始字符串,并将函数的第⼀个参数指针指向分割后的剩余字符串。它适⽤于分割关键字在两个字符串之间只严格出现⼀次的情况。
PS:
因为函数内部会修改原字符串变量,所以传⼊的参数不能是不可变字符串(即⽂字常量区)。
如 char *tokenremain ="abcdefghij"//编译时为⽂字常量,不可修改。
strtok(tokenremain,"cde");
strsep(&tokenremain,"cde");
编译通过,运⾏时会报段错误。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论