关于strtok和strtok_s函数
最近看了《征服C指针》第二版,6.1.2节中提到了strtok函数和strtok_s函数。
strtok
关于strtok的用法,见下面代码:
#include<stdio.h>
#include<string.h>
using namespace std;
int main(){
char s[]="int,short,char,double,float";
char *t;
t=strtok(s,",");
puts(t);
t=strtok(NULL,",");
puts(t);
t=strtok(NULL,",");
puts(t);
}
通过这种方式,可以依次取出以逗号分隔的令牌。运行结果:
注意点:
1.仅在第一次调用时,将字符串传给第一个参数,第二次及以后的调用,第一个参数全部放NULL。
2.之所以能够以这样的方式分割令牌,是因为strtok的内部通过静态变量保存了指向“剩下的字符串”的开头的指针。
3.因此,这样的设计下,当一个地方在使用strtok时,程序的其他地方是无法使用strtok的,而且例如字符串既有逗号分隔的信息也有冒号分隔的信息时,也无法在同时处理逗号分隔的信息和冒号分隔的信息。
4.strtok以空字符结束返回的令牌(变量t),但是会破坏原字符串,是在原字符串插入空字符。
#include<stdio.h>
#include<string.h>
using namespace std;
int main(){
char s[]="int,short,char,double,float";
char *t;
t=strtok(s,",");
puts(t);
puts(s);//"int"
}
注意这里输出s时,只输出了int。这种设计让人感觉不太好,不过也勉强可以接受。
strtok_s(C11)
这是C11标准新增的函数。
引用自《征服C指针》第二版:
ptr这里就是调用方分配的一个指针,指向剩余字符串的开头。因为要在函数体内修改,因此指针传递,也就是“指向指针的指针”。替代了原先strtok内部的静态变量,因此可以在多个地方同时使用strtok_s了。
s1max存放剩余的字符个数,每调用一次strtok_s,它的值都会相应减少。
代码的写法
char *str="abc,def,ghi,jkl,mno";
char *t;
rsize_t s1max=sizeof(str);
char *ptr;
t=strtok_s(str,&s1max,",",&ptr);//abc
t=strtok_s(NULL,&s1max,",",&ptr);//def
t=strtok_s(NULL,&s1max,",",&ptr);//ghi
注:
visual studio中的strtok_s只有三个参数。