字符串分割 strtok strtok_r strsep

来源:互联网 发布:线切割输入编程步骤 编辑:程序博客网 时间:2024/05/16 11:58
来源:点击打开链接

strtok

分解字符串为一组字符串。s为要分解的字符,delim为分隔符字符(如果传入字符串,则传入的字符串中每个字符均为分割符)。首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL。

        函数原型: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)得到各部分子串。

测试代码:

[cpp] view plain copy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3.   
  4. int main(void) {  
  5.     char s[] = "hello, world! welcome to china!";  
  6.     char delim[] = " ,!";  
  7.   
  8.     char *token;  
  9.     for(token = strtok(s, delim); token != NULL; token = strtok(NULL, delim)) {  
  10.         printf(token);  
  11.         printf("+");  
  12.     }  
  13.     printf("\n");  
  14.     return 0;  
  15. }  

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

For example:

  1. char str[] = "now # is the time for all # good men to come to the # aid of their country";  
  2. char delims[] = "#";  
  3. char *result = NULL;  
  4. result = strtok( str, delims );  
  5. while( result != NULL ){  
  6.     printf( "result is \"%s\"\n", result );  
  7.     result = strtok( NULL, delims );  
  8. }  

The above code will display the following output:

  1. result is "now "  
  2. result is " is the time for all "  
  3. result is " good men to come to the "  
  4. result is " aid of their country"   
  1. char str2[] = "2011/11/28";  
  2.     char *buf;  
  3.     char *token;  
  4.     buf = str2;  
  5.     while((token = strsep(&buf, "/")) != NULL){  
  6.         printf("%s\n", token);  
  7.     }  

输出:

  1. 2011  
  2. 11  
  3. 28  


        对于strsep有如下例子:

[cpp] view plain copy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3.   
  4. int main(void) {  
  5.     char source[] = "hello, world! welcome to china!";  
  6.     char delim[] = " ,!";  
  7.   
  8.     char *s = strdup(source);  
  9.     char *token;  
  10.     for(token = strsep(&s, delim); token != NULL; token = strsep(&s, delim)) {  
  11.         printf(token);  
  12.         printf("+");  
  13.     }  
  14.     printf("\n");  
  15.     return 0;  
  16. }  
        输出结果为:hello++world++welcome+to+china++

       为什么用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 (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

*/


原创粉丝点击