在看源码的时候需要将一段并排的IPs转化成为一系列的IP,将"10.0.0.1;10.0.0.2;10.0.0.3;10.0.0.4;10.0.0.5"转换成为单独的"10.0.0.1","10.0.0.2","10.0.0.3","10.0.0.4","10.0.0.5"。就是一个将一个字符串切割成为多个字符串的问题。考虑C语言中的strtok以及strtok函数。
1.strtok
原型:char *strtok(char s[], const char *delim)
功能:分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。
2.strtok_r
原型:char *strtok_r(char *str, const char *delim, char **saveptr)
strtok_r函数是strtok函数的可重入版本。str为要分解的字符串,delim为分隔符字符串。char **saveptr参数是一个指向char *的指针变量,用来在strtok_r内部保存切分时的上下文,以应对连续调用分解相同源字符串。
函数strtok_r是函数strtok的可重入版本,也即线程安全版本。在函数strtok中剩余字符串是存储在一个静态变量中,因此,多线程在使用该静态变量时引起冲突;而strtok_r则使用用户传入的指针为每个用户saveptr重新申请变量,因而可以保证线程安全。
可重入函数:重入即表示重复进入,首先它意味着这个函数可以被中断,其次意味着它除了使用自己栈上的变量以外不依赖于任何环境(包括static),这样的函数就是purecode(纯代码)可重入,可以允许有该函数的多个副本在运行,由于它们使用的是分离的栈,所以不会互相干扰。如果确实需要访问全局变量(包括static),一定要注意实施互斥手段。可重入函数在并行运行环境中非常重要,但是一般要为访问全局变量付出一些性能代价。
举个栗子:
#include<iostream>运行结果:
#include<cstdlib>
#include<string.h>
using namespace std;
int strtok(char *pSrc)
{
char *pToken = NULL;
char *pDelimiter = ";";
pToken = strtok(pSrc,pDelimiter);
cout<<"Strtok Begin:"<<endl;
while(pToken)
{
cout<<"pToken:"<<pToken<<endl;
pToken = strtok(NULL,pDelimiter);
}
cout<<"Strtok End!"<<endl<<endl;
}
int strtok_r(char *pSrc)
{
char *pToken = NULL;
char *pLeft = NULL;
char *pDelimiter = ";";
pToken = strtok_r(pSrc,pDelimiter,&pLeft);
cout<<"Strtok_r Begin:"<<endl;
while(pToken)
{
cout<<"pToken:"<<pToken<<" pLeft:"<<pLeft<<endl;
pToken = strtok_r(NULL,pDelimiter,&pLeft);
}
cout<<"Strtok_r End!"<<endl<<endl;
}
int main()
{
char pSrc[] = "10.0.0.1;10.0.0.2;10.0.0.3;10.0.0.4;10.0.0.5;10.0.0.6";
strtok(pSrc);
char pSrc1[] = "10.0.0.1;10.0.0.2;10.0.0.3;10.0.0.4;10.0.0.5;10.0.0.6";
strtok_r(pSrc1);
return 0;
}
Author:忆之独秀
Email:leaguenew@qq.com
注明出处:http://blog.csdn.net/lavorange/article/details/47134121