一、介绍
char *strtok(char *str, const char *delim)
功能:作用于字符串str,以delim中的字符为分界符,将str切分成一个个子串,该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。
二、实例
实例一,分割字符串的基本用法,分割字符“-”,打印分割后的子字符串
#include <string.h>
#include <stdio.h>
int main () {
char str[80] = "This is - www.runoob.com - website";
const char s[2] = "-";
char *token;
/* 获取第一个子字符串 */
token = strtok(str, s);
/* 继续获取其他的子字符串 */
while( token != NULL ) {
printf( "%s\n", token );
token = strtok(NULL, s);
}
return(0);
}
这里需要注意的是,在对一个长字符串分割的时候,第一次调用时,strtok函数的第一个参数传入要分割的字符串,而第二次以及后面再次调用该函数的时候,strtok函数的第一个参数应该传入NULL,这是因为在strtok第一个参数为NULL的时候,该函数默认使用上一次未分割完的字符串的未分割的起始位置作为本次分割的起始位置,直到分割结束为止。
运行结果
现在,我们打印下分割后的原始str,
#include <string.h>
#include <stdio.h>
int main () {
char str[80] = "This is - www.runoob.com - website";
const char s[2] = "-";
char *token;
/* 获取第一个子字符串 */
token = strtok(str, s);
/* 继续获取其他的子字符串 */
while( token != NULL ) {
printf( "%s\n", token );
token = strtok(NULL, s);
}
printf( "%s\n", str);
return(0);
}
运行结果
你以为str变为第一个分割的字符串了,错错错,我们如果是这样打印,str又变了
#include <string.h>
#include <stdio.h>
int main()
{
char str[80] = "This is - www.runoob.com - website";
const char s[2] = "-";
char *token;
/* 获取第一个子字符串 */
token = strtok(str, s);
/* 继续获取其他的子字符串 */
while (token != NULL)
{
printf("%s\n", token);
token = strtok(NULL, s);
}
printf("\n");
for (int i = 0; i < 34;i++){
printf("%c", str[i]);
}
return (0);
}
运行结果
原来,原字符串的改动是将分割符原位置均更改为 '\0',内容却都还在。
实例二
// 例1
#include <string.h>
void main()
{
char s[] = ".192.168.0.26";
const char *delim = ".";
char *p;
printf("%s ", strtok(s, delim));
while((p = strtok(NULL, delim))){
printf("%s ", p);
}
printf("\n");
}
如果strtok函数要分解的字符串的首字符就是分隔符,那么strtok函数会忽略第一个字符,直接从下一个分隔符算起。比如:".192.168.0.26",那么第一个字符'.'就会被忽略,分解后的第一个字符串就是"192"。
运行结果
三、总结
总之,strtok函数是一个看起来很简单,但是使用起来有很多需要注意的细节的函数,所以应该理解掌握,需要注意的是,使用该函数进行字符串分割时,会破坏被分解字符串的完整,调用前和调用后的s已经不一样了。第一次分割之后,原字符串str是分割完成之后的第一个字符串,剩余的字符串存储在一个静态变量中,因此多线程同时访问该静态变量时,则会出现错误。所以很多情况下并不再使用这个函数,而是由程序员实现自己的字符串分割函数,从而保证线程安全,
strtok_s函数
strtok_s是windows下的一个分割字符串安全函数,其函数原型如下:
char *strtok_s( char *strToken, const char *strDelimit, char **buf);
这个函数将剩余的字符串存储在buf变量中,而不是静态变量中,从而保证了安全性。
strtok_r函数
strtok_s函数是linux下分割字符串的安全函数,函数声明如下:
char *strtok_r(char *str, const char *delim, char **saveptr);
该函数也会破坏带分解字符串的完整性,但是其将剩余的字符串保存在saveptr变量中,保证了安全性。
参考: