首页 > 其他分享 >strtok() 函数 2种方法的指针实现

strtok() 函数 2种方法的指针实现

时间:2023-05-22 18:25:29浏览次数:40  
标签:last 函数 strtok char str return NULL string 指针

//Lvxin4 - 1  strtok.cpp  //strtok()函数的实现  2种方法


//下面的函数实现考虑一下3种极端情况:
//"- This, a sample string" 无行尾标志
//"- This, a sample string-" 有一个行尾标志
//"- This, a sample string- - - - --”  有多个行尾标志


#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

//方法1  纯指针实现



char* StringSplit(char* str, const char* s)
{
    static char* last = NULL;
    if (!str)//if(str == NULL)  //记忆上次输出字符串的下个位置
        str = last;
    if (!str)
        return NULL;

    while (*str)
    {
        char c = *str;
        const char* q = s;
        while (*q != c && *q)  //循环找到str串中第一个字符c
            ++q;
        if (*q == '\0')   //找到每个字符串的入口
        {
            char* p = str;//strpbrk(str, s);
            while (c = *p) //在str串中首个找到的位置开始循环,直到结束‘\0’,逐个找字符串
            {
                q = s; //str中的每个字符逐个和s串进行比较
                while (c != *q && *q) //如果*q==c ,就是c为s中字符,*q不为0,结束循环,为进入if条件
                    ++q;
                if (*q)//代表发现尾部的分隔符  //找到s中的相关字符
                {
                    *p = '\0'; //把找到的第一个至为0
                    last = p + 1;//记录下一个位置,未下次循环str的起始位置
                    return str;//返回str串的首个位置,打印找到的str串             
                }
                ++p;
            }

            if (c == '\0') //这两行老师程序里没有,导致程序出现bug。当出现"- This, a sample ++string"时,*q为0,直接返回str最后一个字符串string,last没有记录,导致下次出现是last还是在上个位置,last记录为+string的+号位置,打印出现死循环。
            {
                last = NULL;
                return str;
            }

            return str;
        }
        ++str;
    }

    last = NULL;  //str每个字符都循环完毕后,把静态变量的last置空,干活要利落!!,其实不置空也行。
    return NULL;
}

 


//方法2  用含有strchr() strpbrk() 函数的方法实现
char* StringSplit(char* str, const char* s)
{
    static char* last = NULL;
    if (!str)//if(str == NULL)
        str = last;
    if (!str)
        return NULL;       //此语句对应列子如"- This, a sample string" 这种情况 ,行尾无对应
    if (*str == '\0')
        return NULL;   // 此语句对应列子如"- This, a sample string-" 这种情况,行尾有1个对应,当下方语句为while(*str)时,也可省率此句

    while (*str)
    {
        if (!strchr(s, *str))  //找到子串的入口
        {
            char* p = strpbrk(str, s);  //找到str串中子串的第一个s串的字符
            if (p)  //把第一个子串结尾的s字符置为0,记录下一个位置
            {
                *p = '\0';
                last = p + 1;
            }

            if (p == NULL)
                last = NULL;  // 这两行老师程序里没有,导致程序出现bug。当str末尾没有对应的s字符,也就是 "- This, a sample string" 这种情况,只有行结束标志‘\0’,打印会出现死循环。因为当p指向最后一个单词的行尾,没有对应的s字符,会给p返回一个空指针,打印完最后一个str后,last还在上个位置停留,再次调用时,不停打印str最后一个字符创,出现死循环。

            return str;
        }
        ++str;
    }
    last = NULL;//此语句我看来可以省去,写上此句后可使全局变量区清理干净,干活利落!!
    return NULL;
}


//主函数main()入口
int main()
{
    char str[] = "- This, a sample string.";
    const char* pch;
    printf("Splitting string \"%s\" into tokens:\n", str);
    pch = StringSplit(str, " ,.-");
    while (pch != NULL)
    {
        printf("%s\n", pch);
        pch = StringSplit(NULL, " ,.-");
    }
    return 0;
}

标签:last,函数,strtok,char,str,return,NULL,string,指针
From: https://www.cnblogs.com/blogofchensen/p/17421384.html

相关文章

  • Jasypt和Druid加解密函数
    springbootjasypt加解密jasypt加密ENC()需要启动参数秘钥Druid加密,需要public-key  packagecom.example.demo;importcom.alibaba.druid.filter.config.ConfigTools;importorg.jasypt.encryption.pbe.PooledPBEStringEncryptor;importorg.jasypt.encryption......
  • 函数递归
    【一】函数递归【1】函数递归介绍函数不仅可以嵌套定义,还可以嵌套调用即在调用一个函数的过程中,函数内部又调用另一个函数而函数的递归调用指的是在调用一个函数的过程中又直接或间接地调用该函数本身在调用f1的过程中,又调用f1这就是直接调用函数f1本身deff1():......
  • strtok() 函数 2种方法的指针实现
    //Lvxin4-1strtok.cpp//strtok()函数的实现2种方法//下面的函数实现考虑一下3种极端情况://"-This,asamplestring"无行尾标志//"-This,asamplestring-"有一个行尾标志//"-This,asamplestring------”有多个行尾标志define_CRT_SECURE_NO_WARNING......
  • MySQL常用关键字和函数及部分关键字使用场景
    世间情动,不过盛夏白瓷梅子汤,碎冰碰壁当啷响。一,关键字使用顺序在使用SQL查询时,关键字的顺序并不是非常重要,SQL解释器可以根据查询的语法结构自动推断其执行顺序。但是,为了使查询更加易读,并且能够避免出现在结果中无法预期的重复数据,建议始终按照以下顺序使用关键字:1,SEL......
  • 指针和地址变量
    理解指针和地址变量的区别,以及如何正确进行函数传参指针和地址变量的区别:指针是一种变量,它存储的是另一个变量的地址(内存地址)。指针通过存储地址来间接操作某个变量。2.地址变量是存储某个变量地址的普通变量。它直接存储地址这个数值。例如:inta=10;int*p=&a;......
  • C++ inline 函数(转)
    (一)inline函数(摘自C++Primer的第三版)在函数声明或定义中函数返回类型前加上关键字inline即把min()指定为内联。inlineintmin(intfirst,intsecend){/****/};     inline函数对编译器而言必须是可见的,以便它能够在调用点内展开该函数。与非inline函数不同的是,inline函数必......
  • 实验四 函数与异常编程处理
    实验任务1task1-1实验源码print(sum)sum=42print(sum)definc(n):sum=n+1print(sum)returnsumsum=inc(7)+inc(7)print(sum)实验截图问题:task1.py源码中,共有4处有python语句print(sum)(line1,line3,line7,line11)。这4处使用的标识......
  • 14-DSL查询语法-复合查询-算分函数查询
     复合(compound)查询:复合查询可以将其它简单查询组合起来,实现更复杂的搜索逻辑。常见的有两种:(1)fuctionscore:算分函数查询,可以控制文档相关性算分,控制文档排名(2)boolquery:布尔查询,利用逻辑关系组合多个其它的查询,实现复杂搜索 相关性算分当我们利用match查询时,文档结果会根据......
  • Perl:sprintf函数
    在Perl中,sprintf是一个用于格式化字符串的函数。它接受一个格式字符串和一系列参数,并返回根据格式字符串格式化后的字符串。sprintf的语法如下:sprintfFORMAT,LIST其中,FORMAT是格式字符串,指定了输出的格式。LIST是需要格式化的参数列表。sprintf将根据格式字符串对参数......
  • Python 2-04 匿名函数
    Python匿名函数一、匿名函数lambdaλlambda[args]:expression即lambda[参数列表]:表达式lambda_add=lambdax,y:x+ydefnormal_add(x,y):returnx+yassertlambda_add(2,3)==normal_add(2,3)注:assertexpression[,arguments]即:assert表达式......