C语言字符串分割的几种(4种)方法

在C语言中,字符串分割是常见的需求,比如文件路径处理、网络协议解析、配置文件解析、命令行参数处理、日志分析等操作都需要用到C语言字符串分割。

下面介绍c语言中几种(4种)字符串分割的方法,通过例子、函数定义、参数说明,并介绍它们的使用场景和区别。

1. 使用 strtok 函数

它是标准库函数,简单易用,它是非线程安全的可用 strtok_r 替代使用。

下面看使用例子。

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

int main() {
    char str[] = "hello,world,online,compiler";
    const char delim[] = ",";
    char *token = strtok(str, delim);

    while (token != NULL) {
        printf("%s\n", token);
        token = strtok(NULL, delim); // 继续分割剩余部分
    }
    return 0;
} 

函数定义

char *strtok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim, char **saveptr); // 线程安全版本
参数说明

str:待分割的字符串(首次调用时传入,后续传NULL)。
delim:分隔符集合(如 "," 或 " ,|"),本例子中使用的是逗号。
saveptr(仅strtok_r):用户提供的指针,用于保存分割状态。
返回值

成功:返回当前分割出的子字符串指针。
结束:返回NULL(无更多子字符串)。

2. 使用 strsep 函数

它是BSD扩展,类似 strtok,但更灵活,支持空字符串和连续分隔符。

它是非线程安全的,可能会修原字符串。

看下面的例子。

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

int main() {
    char str[] = "hello,world,online,compiler";
    const char delim[] = ",;";
    char *token, *rest = str;

    while ((token = strsep(&rest, delim)) != NULL) {
        if (*token != '\0') // 忽略空字符串
            printf("%s\n", token);
    }
    return 0;
}

函数定义

char *strsep(char **stringp, const char *delim);

参数说明

stringp:指向待分割字符串的指针,函数会修改此指针的值。
delim:分隔符集合。

返回值

成功:返回当前子字符串指针。
结束:返回NULL。

3. 自定义分割函数

不使用内置函数,自定义实现字符串分割,适合更为灵活的处理.

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

void split_string(const char *str, char delim) {
    int start = 0;
    for (int i = 0; str[i] != '\0'; i++) {
        if (str[i] == delim) {
            printf("%.*s\n", i - start, str + start);
            start = i + 1;
        }
    }
    printf("%s\n", str + start); // 打印最后一段
}

int main() {
    split_string("hello,world,online,compiler", ',');
    return 0;
} 

4. 使用 sscanf 格式化读取

通过格式化匹配提取子字符串,适合简单固定格式。

它是线程安全的,不修改原字符串,但是灵活性较低。

#include <stdio.h>

int main() {
    char str[] = "hello,world,online,compiler";
    char part1[20], part2[20], part3[20], part4[20];

    sscanf(str, "%[^,],%[^,],%[^,],%s", part1, part2, part3, part4);
    printf("%s\n%s\n%s\n%s\n", part1, part2, part3, part4);

    return 0;
} 

上面的例子中我们可以看出,大多数情况下我们不太愿意使用这样的方法,应为它不是很灵活。

对比区别

方法是否修改原字符串线程安全适用场景
strtok简单快速分割
strtok_r多线程环境
strsep连续分隔符处理
自定义函数自定义复杂需求
sscanf固定格式提取