C语言字符串截取函数strtok和strtok_r

时间:2022-11-12 19:12:24

       在看源码的时候需要将一段并排的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;
}
运行结果:

C语言字符串截取函数strtok和strtok_r


Author:忆之独秀

Email:leaguenew@qq.com

注明出处:http://blog.csdn.net/lavorange/article/details/47134121