zoukankan      html  css  js  c++  java
  • Linux C strtok实现自定义字符串切分函数split


    1. 问题:Linux C如何切分字符串?

    java的String类有split方法,可以将字符串对象按指定字符串进行切分,返回一个数组String[],包含切分后的所有字符串。 Linux C如何对字符串进行切分呢?有没有类似函数/系统调用?
    答:Linux C没有字符串类,也没有split函数,不过有切分字符串的方法:strtok函数。


    2.strtok函数

    提取分隔符间字串。

    strok 有2个版本:strok, strok_r。前者适用于单线程,后者是可重入版本,适用于多线程。
    strok 在一次切分后,能得到分隔符左边的字符串。
    注意:
    1)调用strok会改变传入的str指向的内容,不能是字符串常量,str指向字符串内容为分隔符delim的部分,会被替换为''。
    2)strok是C99, POSIX.1内容,strok_r仅仅是POSIX.1内容。

    strok_r 除了具有strok功能,还能在一次切分后,通过saveptr保存分隔符右边的字符串。

    #include <string.h>
    
    char *strtok(char *str, const char *delim);
    
    char *strtok_r(char *str, const char *delim, char **saveptr);
    
    • 功能
      形如"aaa:bbb"的字符串,strok按分隔符":"对其切分后,得到"aaa"(返回值), 剩余"bbb". strtok_r能同时得到"aaa"(返回值),"bbb"(saveptr)。

    • 参数
      str 待切分字符串,必须是可以修改的字符串,不能是字符串常量。

    delim 分隔符

    saveptr 用于保存strtok_r切分后剩余那部分字符串首地址

    • 返回值
      成功找到分隔符,返回被切分的第一个子字符串;如果没有可检索的字符串,则返回一个空指针。

    用法:
    除第一次调用strtok, 要指明待切分字符串, 后续无需指定, 要用NULL
    形如

    strtok(buf, " "); /* 第一次, 空格切分字符串buf */
    strtok(NULL, " "); /* 第二次, 空格切分字符串buf */
    strtok(NULL, " "); /* 第三次, 空格切分字符串buf */
    ...
    
    或者
    strtok(buf, " "); /* 第一次, 空格切分字符串buf */
    while (( p = strtok(NULL, " ") != NULL) { /* 第二次到第n次切分buf */
        printf("%s
    ", p);
    }
    

    3. strtok切分字符串示例

    char buf[] = "USER 123456 abc @88890
    ";
    
    printf("primary buf = %s
    ", buf);
    
    char *s1 = strtok(buf, " "); /* <SP>切分buf */
    char *s2;
    
    printf("%s
    ", s1);
    while ((s2 = strtok(NULL, " ")) != NULL) {
        printf("%s
    ", s2);
    }
    printf("splited buf = %s
    ", buf);
    

    运行结果:

    primary buf = USER 123456 abc @88890
    
    USER
    123456
    abc
    @88890
    
    splited buf = USER
    

    可以看到,原始字符串buf被修改了。实际上,是buf中分隔符所在位置,都被替换成了''。


    4. strtok_r使用示例

    利用strtok_r,将字符串buf按分隔符" "()分隔为2部分,分别保存到s1, s2 (2个char *)

        char buf[] = "USER 123456 abc @88890
    ";
        char *s1;
        char *s2;
    
        printf("primary buf = %s
    ", buf);
    
        s1 = strtok_r(buf, " ", &s2);
        printf("s1 = %s
    ", s1);
        printf("s2 = %s
    ", s2);
    
        printf("strtok_r buf = %s
    ", buf);
    

    运行结果:

    primary buf = USER 123456 abc @88890
    
    s1 = USER
    s2 = 123456 abc @88890
    
    strtok_r buf = USER
    

    5. 自定义字符串函数split实现

    受4的启发,strtok_r将字符串buf分隔为2部分,分别用2个char *指针标记。

    4的问题是,2个char *指针,并未保存切分后字符串,指示用2个指针保存了原来缓存中的切分位置。能否实现一个函数,将字符串切分后,保存到2个字符串缓存?
    答:是可以的,自定义切分函数strex_split实现见下

    void strex_split(char *s, char *left, char *right, const char* delim)
    {
        char *s1, *s2;
        s1 = strtok_r(s, delim, &s2);
    
        strcpy(left, s1);
        strcpy(right, s2);
    }
    

    其中,left, right是需要调用者提供的缓存。

  • 相关阅读:
    LIKE语句也可以这样写
    a链接触发javascript函数导致innerHTML里的图片无法加载
    引用类型真屌
    网站建设心得
    SPAN
    Go! 环境配置和入门
    linux内核编译
    面试题
    KCMT开源控件之方便简洁的分页控件
    c#中out、ref和params的用法与区别
  • 原文地址:https://www.cnblogs.com/fortunely/p/14986063.html
Copyright © 2011-2022 走看看