分割字符串

很多时候为了方便,会将多个字段的值用特定的符号分隔拼成一个字符串发送,而接收端则需要拆分解析得到各个字段的值,以下是几种常见的做法。

利用strsep函数

函数原型为:char *strsep(char **stringp, const char *delim);

void split1(char *str, char *delim) {
    char *token;
    for (token = strsep(&str, delim); token; token = strsep(&str, delim))
        printf("[%s]", token);
    puts("");
}

例如输入字符串为:

chenfy:x:1000:1000::/home/chenfy:/bin/bash

分隔符为冒号,运行结果为:

[chenfy][x][1000][1000][][/home/chenfy][/bin/bash]

通过strtok函数

该函数与strsep类似,原型为:char *strtok(char *str, const char *delim);

void split2(char *str, char *delim) {
    char *token;
    for (token = strtok(str, delim); token; token = strtok(NULL, delim))
        printf("[%s]", token);
    puts("");
}

对于同样的输入字符串结果为:

[chenfy][x][1000][1000][/home/chenfy][/bin/bash]

strtok函数内部使用了静态变量,不可重入,因此只能用在单线程环境中。如果需要在多线程环境中使用,应改用线程安全版本strtok_r。

函数原型为:char *strtok_r(char *str, const char *delim, char **saveptr);

void split3(char *str, char *delim) {
    char *token, *p;
    for (token = strtok_r(str, delim, &p); token; token = strtok_r(NULL, delim, &p))
        printf("[%s]", token);
    puts("");
}

自定义分割函数

strsep不是标准的C库函数,可移植性不如strtok,另外strsep同样存在线程不安全的问题,但它有个特点有些时候很有用:连续出现分隔符出来的是空字符串。

下面是自己实现的分割函数。

int split(char *str, char delim, char buf[][64]) {
    int p1 = 0, p2 = 0, cnt = 0, len = 1 + strlen(str);
    while (p1 < len) {
        while (str[p2] && str[p2] != delim) p2++;
        str[p2] = 0;
        strcpy(buf[cnt++], str + p1);
        p1 = p2 = p2 + 1;
    }
    return cnt;
}
Table of Contents