c语言里面常用的字符串分割函数有strtok和strsep,两者原型定义及说明如下:
一,strtok函数
1.原型:char *strtok(char *s, const char *delim);
2.功能:分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。
3.说明:
strtok()用来将字符串分割成一个个片段。参数s指向欲分割的字符串,参数delim则为分割字符串,当strtok()在参数s的字符串中发现到
参数delim的分割字符时则会将该字符改为\0
字符。在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。每次调用成功则返回下一个分割后的字符串指针。
4.返回值:
从s开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。
所有delim中包含的字符都会被滤掉,并将被滤掉的地方设为一处分割的节点。
5.程序示例:
#include
#include
int main(int argc,char * argv[])
{
char input[16] = "abc,d";
char *p;
p = strtok(input, ",");
if (p)
printf("%s\n", p);
p = strtok(NULL, ",");
if (p)
printf("%s\n", p);
return 0;
}
二,strsep函数
1.原型:char *strsep(char **stringp, const char *delim);
2.功能:
分解字符串为一组字符串。从stringp指向的位置起向后扫描,遇到delim指向位置的字符后,将此字符替换为NULL,返回stringp指向的地址。
3.程序示例:
示例程序<1>:
#include
int main(int argc,char *argv[])
{
char string[] = "words separated by spaces";
char *running;
char *token;
running=string;
while((token = strsep (&running," "))!=NULL)
printf("%s\n",token);
return 0;
}
示例程序<2>:
#include
#include
#define STR "1:12::34:6"
int main(int argc,char *argv[])
{
char test_string[100];
char *p,*k;
int i;
k = test_string;
strcpy(test_string,STR);
printf("orgin: %s\n",test_string);
for(i=0;i<5;i++){
p = strsep(&k,":");
printf("%s\n",p);
}
printf("after:%s\n",test_string);
return 0;
}
执行结果显示:
orgin: 1:12::34:6
1
12
34
6
after:1
结论:
该函数貌似会破坏原来的字符串!!!
--------------------------------------------------------------------------------------------------------------
如上是应用层程序所使用的字符串分割函数,与此同时,在linux内核中也宣判了strtok函数的死亡。
注:摘自Linux内核2.6.29,说明了这个函数已经不再使用,由速度更快的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
*
* These are buggy as well..
*
* * Fri Jun 25 1999, Ingo Oeser
* - 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 ,
* Matthew Hawkins
* - Kissed strtok() goodbye
*/
--------------------------------------------------------------------------------------------------------------
转l很早有关使用strsep函数使用讨论!
问题标题:为何strsep只能够操作堆中的字符串呢?
#include
#include
struct item
{
char name[32];
char *value;
struct item *next;
};
int main(int argc,char *argv[])
{
char *channel,*start,*end;
struct item test;
snprintf(test.name,31,"%s", "channel");
test.value = (char *)malloc(128);
snprintf(test.value,127,"%s","1-15,17-31,43,55");
if(!strcasecmp(test.name,"channel"))
{
while(channel = strsep(&test.value,","))
{
start = strsep(&channel,"-");
if(channel)
{
end = channel;
printf("include channel start from %s to %s\n",start,end);
}
else
printf("include channel %s\n",start);
}
}
return 0;
}
[root@localhost program]# ./strsep
include channel start from 1 to 15
include channel start from 17 to 31
include channel 43
include channel 55
--------------------------------------------------------------------------------------------------------------
#include
#include
struct item
{
char name[32];
char value[128];
struct item *next;
};
int main(int argc,char *argv[])
{
char *channel,*start,*end;
struct item test;
snprintf(test.name,31,"%s", "channel");
//test.value = (char *)malloc(128);
snprintf(test.value,127,"%s","1-15,17-31,43,55");
if(!strcasecmp(test.name,"channel"))
{
while(channel = strsep(&test.value,","))
{
start = strsep(&channel,"-");
if(channel)
{
end = channel;
printf("include channel start from %s to %s\n",start,end);
}
else
printf("include channel %s\n",start);
}
}
return 0;
}
[root@localhost program]# ./strsep
Segmentation fault
--------------------------------------------------------------------------------------------------------
修改后无问题源码:
#include
#include
struct item
{
char name[32];
char value[128];
struct item *next;
};
int main(int argc,char *argv[])
{
char *channel,*start,*end,*p;
struct item test;
snprintf(test.name,31,"%s", "channel");
//test.value = (char *)malloc(128);
snprintf(test.value,127,"%s","1-15,17-31,43,55");
if(!strcasecmp(test.name,"channel"))
{
p = test.value;
while(channel = strsep(&p,","))
{
start = strsep(&channel,"-");
if(channel)
{
end = channel;
printf("include channel start from %s to %s\n",start,end);
}
else
printf("include channel %s\n",start);
}
}
return 0;
}
--------------------------------------------------------------------------------------------------------
(1)多谢各位,不过我一直都没有注意过char ** 和char *[]的区别,因为总是看到 int main(int argc, char
*argv[]) 和int main(int argc, char **argv)这两种写法,似乎都把这两种类型当着一样的而没有区分。去看看这两个究竟有什么区别!
(2)看了一圈,大致明白char ** 和char *[]的区别了,确切的说在strsep里是因为char * 和char
[]这两者的区别引起的。char *纯粹是一个指针,它指向的地方可以更改,而char []虽然平时把它和char
*同等对待,但是它所指向的地方却不能更改。
--------------------------------------------------------------------------------------------------------
阅读(7176) | 评论(1) | 转发(1) |