strtok,strtok_r,strtsep

分割字符串的时候,一般想到用strtok,但是该函数使用时需要很小心,而且结果有的时候让人费解。

比如说网上这段代码:

比如,分隔符=“,” 字符串=“Fred,John,Ann”
通过strtok 就可以把3个字符串 “Fred”      “John”       “Ann”提取出来。
上面的C代码为
QUOTE:
int in=0;
char buffer[]="Fred,John,Ann"
char *p[3];
char *buff = buffer;
while((p[in]=strtok(buf,","))!=NULL) {
in++;
buf=NULL; }如上代码,第一次执行strtok需要以目标字符串的地址为第一参数(buf=buffer),之后strtok需要以NULL为第一参数 (buf=NULL)。指针列p[],则储存了分割后的结果,p[0]="John",p[1]="John",p[2]="Ann",而buf就变 成    Fred\0John\0Ann\0。

使用

for(i=0; i<in ;i++)

   printf("%s \n", p[i]);

程序的运行结果和你想的不一样,p[0]="",p[1]="John",p[2]="Ann",注意此时p[0]为空不是网上那样的答案。使用gdb查看循环里面的值,发现更让人费解。在while循环里面gdb查看p[0]的值,p[0]="John"一直如此,但是当程序退出循环时,p[0]发生了变化。

在这里我不得不吐槽以下中国的程序员缺乏认真的态度,总是转载东西,修改都不修改,比如说QUOTE里面的程序有很多处明显错误,都没有人去修改。比如把

buff 写成buf,缺分号啥的,等等。

还有就是更无语的,http://zhwen.org/tools/clib/string/strtok.html该网址里面是介绍一些库函数,给的所谓的案例程序明显就是错误的,无法运行的,有段错误。因为strtok的实现机制修改了传入字符串内容,

char *s="Golden Global View";这个使用的字符常量,是不可修改的。应该使用数组,数组是放在栈上的。
网上找了资料,发现什么strtok,strtok_r的区别啊,在于代码的可插入,最后找到亮点了发现linux早就有更好的实现即strsep,该函数不仅可重入,且运行效率更快,更好使用。

strsep(),作为strtok的升级版,是一个很有用的字符串处理函数, 但是也有很多不方便的地方, 使用时需特别小心, 好在注意的事项都在 man strsep 里面有。如下:

#include <string.h>

char *strsep(char **stringp, const char *delim); 

Be cautious when using this function.  If you do use it, note that: * This function modifies its first argument.

* This function cannot be used on constant strings.

* The identity of the delimiting character is lost.

自己写了一个小程序测试以下

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX 5
int main(int arg, const char *argv[])
{
    int in=0;
    char* string = strdup( "/home/yinlijun/project:/home/yinlijun:/home/someone");          /*字符串不能为常量,所以strdup*/
    char *p[MAX];
    while((p[in] = strsep(&string, ":")) != NULL)        /*第一个参数设为二级指针, 字符串中所有的第二个参数(子串)最后会被替代成‘/0’*/ 
    {
	in++;
    }
    int i;
    for(i=0; i < in ;i++ )
	printf("%s\n", p[i]);
    free(string);
    return 0;
}
<span style="font-family: Arial, Helvetica, sans-serif;">总之,一句话,网上找资料真的是太麻烦了,很多人几乎就是原样转载。</span>



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值