C语言strtok函数详解与使用技巧

目录

介绍

函数原型

工作原理

核心特性

修改原字符串

连续分隔符被忽略

不可重入/非线程安全

字符串结束

使用步骤

线程安全替代方案

[strtok_r(POSIX 标准)](#strtok_r(POSIX 标准))

[strtok_s(C11 标准)](#strtok_s(C11 标准))

注意事项

空字符串处理

不可嵌套调用

分隔符为单字符

总结表格


介绍

strtok 是 C 标准库(<string.h>)中用于分割字符串的函数。它将一个字符串按指定的分隔符拆分成多个子字符串(标记)。

函数原型

cpp 复制代码
char *strtok(char *str, const char *delim);
  • str: 待分割的字符串(首次调用传入);后续调用需传入 NULL(表示继续分割同一字符串)。

  • delim: 包含分隔符的字符串(每个字符都认为是分隔符)。

  • 返回值:返回下一个标记的指针;无更多标记时返回 NULL

工作原理

  • 第一次调用时,函数会查找字符串str中第一个不在delim中的字符(即标记的开始)。
  • 然后从该位置开始,继续查找在delim中的字符(即标记的结束位置),并将其替换为'\0'(字符串结束符),这样就得到了一个标记。
  • 函数返回指向该标记的指针。
  • 后续调用时,第一个参数传入NULL,函数会从上一次保存的位置继续查找下一个标记。

核心特性

修改原字符串

strtok 会直接修改原始字符串,将分隔符替换为 '\0'。若需保留原字符串,应先拷贝。

连续分隔符被忽略

如果字符串中有连续的分隔符,strtok会跳过它们,即不会返回空字符串。

不可重入/非线程安全

函数内部使用静态变量记录位置。多线程中应用 strtok_r(POSIX)或 strtok_s(C11)。

字符串结束

当没有更多标记时,函数返回NULL。

使用步骤

  • 首次调用:传入目标字符串和分隔符。

  • 后续调用 :传入 NULL 和分隔符(继续分割同一字符串)。

  • 结束条件 :返回 NULL 时表示无更多标记。

cpp 复制代码
#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "apple,banana,,cherry;date";
    char *token = strtok(str, ",;"); // 第一次调用,传入字符串    分隔符为逗号或分号 

    while (token != NULL) {
        printf("Token: %s\n", token);
        token = strtok(NULL, ",;"); // 继续分割  后续调用传入NULL
    }

    return 0;
}

 
// 输出   注意:连续的分隔符 ,, 被忽略,未产生空标记。
// Token: apple
// Token: banana
// Token: cherry
// Token: date

线程安全替代方案

strtok_r(POSIX 标准)

cpp 复制代码
char *strtok_r(char *str, const char *delim, char **saveptr);
cpp 复制代码
// saveptr:用户提供的指针,用于保存分割状态

char *saveptr;
token = strtok_r(str, ",;", &saveptr);
while (token) {
    // 处理 token
    token = strtok_r(NULL, ",;", &saveptr);
}

strtok_s(C11 标准)

cpp 复制代码
char *strtok_s(char *str, const char *delim, char **context);
cpp 复制代码
// context:类似 saveptr 的上下文指针。
char *context = NULL;
token = strtok_s(str, ",;", &context);
// 使用方式同 strtok_r

注意事项

空字符串处理

若字符串全部分隔符或无有效内容,首次调用即返回 NULL。

cpp 复制代码
char s[] = ";;;";
char *t = strtok(s, ";"); // t = NULL

不可嵌套调用

同一线程内不可嵌套使用 strtok(因共享静态状态)。

分隔符为单字符

如果delim 是字符串(如 ";,"),则字符串里的每个字符(;,)都是独立分隔符。

总结表格

特性 说明
是否修改原字符串 是(分隔符替换为 \0
连续分隔符 被忽略
线程安全 否(用 strtok_r/strtok_s 替代)
首次调用参数 传入目标字符串指针
后续调用参数 传入 NULL
结束条件 返回 NULL

掌握 strtok 的关键是理解其修改原字符串静态状态记录的特性,合理使用时注意线程安全和字符串备份!

相关推荐
lcj251114 小时前
【C语言】自定义类型1:结构体
c语言·开发语言·算法
cmpxr_14 小时前
【C】隐式类型转换
c语言·c++·算法
泛凡(Linyongui)14 小时前
PY32F002B实践之三--宠物腹背理疗仪项目功能代码分析说明
c语言·keil·32位单片机·腹背理疗仪项目实践·普苒py32
智者知已应修善业15 小时前
【51单片机独立按键控制数码管动态显示和LED间隔闪烁并清零】2023-5-28
c语言·经验分享·笔记·算法·51单片机
水云桐程序员15 小时前
用C语言开发单片机项目的工作思路
c语言·开发语言·单片机
她说彩礼65万15 小时前
C语言 指针运算
c语言·数据结构·算法
weixin_446023561 天前
C语言:面向过程、应用底层开发、跨平台的通用程序设计语言
c语言·跨平台·数据类型·底层开发·面向过程
无敌昊哥战神1 天前
深入理解 C 语言:巧妙利用“0地址”手写 offsetof 宏与内存对齐机制
c语言·数据结构·算法
cmpxr_1 天前
【C】数组名、函数名的特殊
c语言·算法
itman3011 天前
C语言怎么学?从写程序到玩指针的实操攻略
c语言·指针·结构体·编程学习·资源推荐