在C语言中,字符串分割是常见的需求,比如文件路径处理、网络协议解析、配置文件解析、命令行参数处理、日志分析等操作都需要用到C语言字符串分割。
下面介绍c语言中几种(4种)字符串分割的方法,通过例子、函数定义、参数说明,并介绍它们的使用场景和区别。
它是标准库函数,简单易用,它是非线程安全的可用 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(无更多子字符串)。
它是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。
不使用内置函数,自定义实现字符串分割,适合更为灵活的处理.
#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;
}
通过格式化匹配提取子字符串,适合简单固定格式。
它是线程安全的,不修改原字符串,但是灵活性较低。
#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 | 否 | 是 | 固定格式提取 |