C语言中strtok和strtok_r

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

int main() {
// 原始数据
char input[] = “7,A7B1,2.0175,270.4543”;

// 定义变量
int num7 = 0;
int a_num = 0;
int b_num = 0;
double d1 = 0.0;
double d2 = 0.0;

// 分割字符串
char *token = strtok(input, ",");

// 处理第一个值(7)
if (token) num7 = atoi(token);

// 处理第二个值(A7B1)
if ((token = strtok(NULL, ","))) {
    char *a_ptr = strchr(token, 'A');
    char *b_ptr = strchr(token, 'B');
    
    if (a_ptr && *(a_ptr+1)) a_num = atoi(a_ptr+1);
    if (b_ptr && *(b_ptr+1)) b_num = atoi(b_ptr+1);
}

// 处理第三个值(2.0175)
if ((token = strtok(NULL, ","))) d1 = atof(token);

// 处理第四个值(270.4543)
if ((token = strtok(NULL, ","))) d2 = atof(token);

// 验证输出
printf("num7 = %d\n", num7);
printf("a_num = %d\n", a_num);
printf("b_num = %d\n", b_num);
printf("d1 = %.4f\n", d1);
printf("d2 = %.4f\n", d2);

return 0;

}
fukaiwan 16:38:22

strtok_r 是 C 语言标准库中用于分割字符串的可重入(线程安全)版本函数,定义在 <string.h> 头文件中。与 strtok 不同,它通过显式维护分割状态,避免了静态缓冲区的限制,适合多线程环境或嵌套调用场景。


函数原型

char *strtok_r(char *str, const char *delim, char **saveptr);

参数说明

  1. str
    • 首次调用时传入待分割的字符串指针,后续调用传入 NULL
  2. delim
    • 分隔符集合字符串(如 ",; " 表示逗号、分号、空格均为分隔符)。
  3. saveptr
    • 用户维护的指针变量地址,用于记录分割进度(需初始化为 NULL)。

返回值

  • 成功时返回当前 token 的指针。
  • 无更多 token 时返回 NULL

核心机制

  1. 显式状态管理
    通过 saveptr 参数保存分割进度,避免 strtok 的静态缓冲区问题。
  2. 修改原字符串
    将分隔符替换为 \0,分割后的字符串与原字符串共享内存。

示例代码

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

int main() {
    char str[] = "Hello,world;this is-a test";
    char *token;
    char *saveptr;  // 用于保存分割状态
    const char delim[] = ",; -";  // 分隔符:逗号、分号、空格、短横线

    // 首次调用,传入字符串和分隔符
    token = strtok_r(str, delim, &saveptr);

    // 后续调用,传入 NULL 和 saveptr
    while (token != NULL) {
        printf("Token: %s\n", token);
        token = strtok_r(NULL, delim, &saveptr);
    }

    return 0;
}

输出

Token: Hello
Token: world
Token: this
Token: is
Token: a
Token: test

关键注意事项

  1. 线程安全
    每个线程使用独立的 saveptr 变量,避免竞争条件。
  2. 原字符串修改
    若需保留原字符串,应先复制(如用 strdup):
    char *copy = strdup(original_str);
    // 使用 copy 分割
    free(copy);  // 释放内存
    
  3. 连续分隔符
    多个连续分隔符视为单个分隔符(如 "a,,b" 分割为 "a""b")。
  4. 嵌套调用
    支持在递归或嵌套循环中分割多个字符串,只需为每个字符串分配独立的 saveptr

对比 strtokstrtok_r

特性strtokstrtok_r
线程安全? 否? 是
静态缓冲区? 是(潜在风险)? 否(用户管理状态)
适用场景单线程简单分割多线程/嵌套分割

典型应用场景

  • 多线程环境下分割字符串(如日志解析)。
  • 同时处理多个字符串(如嵌套解析 "key=value1,value2""name=John;age=30")。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HH予

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值