strtok、strtok_s、strtok_r 字符串分割函数

时间:2021-10-19 19:13:55

经验教训:

在多线程编程时一定要注意函数的可重入性,对于使用静态或全局变量等不可重入的函数进行改造或加锁使其串行化调用,注意掉用的库函数是否是线程安全的,常见的线程不安全函数如strtok、 ctime
原文地址:http://www.cnblogs.com/sdlwlxf/p/4354310.html

1、strtok函数

函数原型:char * strtok (char *str, const char * delimiters);
参数:str,待分割的字符串(c-string);delimiters,分割符字符串。
 
使用方法:该函数用来将字符串分割成一个个片段。参数str指向欲分割的字符串,参数delimiters则为分割字符串中包含的所有字符。当strtok()在参数s的字符串中发现参数delimiters中包涵的分割字符时,则会将该字符改为\0 字符。在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。每次调用成功则返回指向被分割出片段的指针。
 
原理:作用于字符串str,以包含在delimiters中的字符为分界符,将str切分成一个个子串;如果,s为空值NULL,则函数保存的指针SAVE_PTR在下一次调用中将作为起始位置。
 
注意:1.使用该函数进行字符串分割时,会破坏被分解字符串的完整,调用前和调用后的s已经不一样了。第一次分割之后,原字符串str是分割完成之后的第一个字符串, 剩余的字符串存储在一个静态变量SAVE_PTR中,因此多线程同时访问该静态变量时,则会出现错误。
   2.delimiters中包含多字符:GNU C Library中对strtok的功能定义:“Parse S into tokens separated by characters in DELIM”。也就是说包含在delim中的字符均可以作为分隔符,而非严格匹配。可以把delim理解为分隔符的集合。这一点是非常重要的。
   3.如果第一个字符就是分割字符,将自动省略掉
strtok、strtok_s、strtok_r 字符串分割函数
// crt_strtok.c
// compile with: /W3
// In this program, a loop uses strtok
// to print all the tokens (separated by commas
// or blanks) in the string named "string".
//
#include <string.h>
#include
<stdio.h>

char string[] = "A string\tof ,,tokens\nand some more tokens";
char seps[] = " ,\t\n"; // 字符',' '\t' '\n'都作为分割字符
char *token;

int main( void )
{
printf(
"Tokens:\n" );

// Establish string and get the first token:
token = strtok( string, seps ); // C4996
// Note: strtok is deprecated; consider using strtok_s instead
while( token != NULL )
{
// While there are tokens in "string"
printf( " %s\n", token );

// Get next token:
token = strtok( NULL, seps ); // C4996
}
}
strtok、strtok_s、strtok_r 字符串分割函数

 结果:

strtok、strtok_s、strtok_r 字符串分割函数
Tokens:
A
string
of
tokens
and
some
more
tokens
Program ended with exit code:
0
strtok、strtok_s、strtok_r 字符串分割函数

 

2、strtok_s函数

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

3、strtok_r函数

strtok_s函数是linux下分割字符串的安全函数,函数声明如下:
char *strtok_r(char *str, const char *delim, char **saveptr);
该函数也会破坏带分解字符串的完整性,但是其将剩余的字符串保存在saveptr变量中,保证了安全性。