java的String类有split方式,可以将字符串对象按指定字符串进行切分,返回一个链表String[],包含切分后的所有字符串。LinuxC怎样对字符串进行切分呢?有没有类似函数/系统调用?
答:LinuxC没有字符串类linux关机命令,也没有split函数,不过有切分字符串的方式:strtok函数。
2.strtok函数
提取分隔符间字串。
strok有2个版本:strok,strok_r。后者适用于单线程linux c 查找字符串,前者是可重入版本,适用于多线程。
strok在一次切分后,能得到分隔符右边的字符串。
注意:
1)调用strok会改变传入的str指向的内容,不能是字符串常量,str指向字符串内容为分隔符delim的部份,会被替换为''。
2)strok是C99,POSIX.1内容linux c 查找字符串,strok_r仅仅是POSIX.1内容。
strok_r不仅具有strok功能,能够在一次切分后,通过saveptr保存分隔符左边的字符串。
#include
char *strtok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim, char **saveptr);
delim分隔符
saveptr用于保存strtok_r切分后剩余那部份字符串首地址
用法:
除第一次调用strtok,要指明待切分字符串,后续无需指定,要用NULL
形如
strtok(buf, " "); /* 第一次, 空格切分字符串buf */
strtok(NULL, " "); /* 第二次, 空格切分字符串buf */
strtok(NULL, " "); /* 第三次, 空格切分字符串buf */
...
或者
strtok(buf, " "); /* 第一次, 空格切分字符串buf */
while (( p = strtok(NULL, " ") != NULL) { /* 第二次到第n次切分buf */
printf("%sn", p);
}
3.strtok切分字符串示例
char buf[] = "USER 123456 abc @88890n";
printf("primary buf = %sn", buf);
char *s1 = strtok(buf, " "); /* 切分buf */
char *s2;
printf("%sn", s1);
while ((s2 = strtok(NULL, " ")) != NULL) {
printf("%sn", s2);
}
printf("splited buf = %sn", buf);
运行结果:
primary buf = USER 123456 abc @88890
USER
123456
abc
@88890
splited buf = USER
可以看见,原始字符串buf被更改了。实际上,是buf中分隔符所在位置,都被替换成了''。
4.strtok_r使用示例
借助strtok_rlinux服务器维护,将字符串buf按分隔符""()分隔为2部份,分别保存到s1,s2(2个char*)
char buf[] = "USER 123456 abc @88890n";
char *s1;
char *s2;
printf("primary buf = %sn", buf);
s1 = strtok_r(buf, " ", &s2);
printf("s1 = %sn", s1);
printf("s2 = %sn", s2);
printf("strtok_r buf = %sn", buf);
运行结果:
primary buf = USER 123456 abc @88890
s1 = USER
s2 = 123456 abc @88890
strtok_r buf = USER
5.自定义字符串函数split实现
受4的启发,strtok_r将字符串buf分隔为2部份,分别用2个char*表针标记。
4的问题是,2个char*表针,并未保存切分后字符串,指示用2个表针保存了原先缓存中的切分位置。能够实现一个函数,将字符串切分后,保存到2个字符串缓存?
答:是可以的,自定义切分函数strex_split实现见下
void strex_split(char *s, char *left, char *right, const char* delim)
{
char *s1, *s2;
s1 = strtok_r(s, delim, &s2);
strcpy(left, s1);
strcpy(right, s2);
}
其中,left,right是须要调用者提供的缓存。