strtok() 用于将字符串 str 按指定的分隔符 delim 进行分割,返回指向每个子串的指针。第一次调用时传入原字符串 str。后续调用时传入 NULL,继续从上一次分割的位置继续分割。trtok() 适合简单的字符串分割会破坏原字符串(如果不想破坏原字符串,可先 strcpy() 复制一份),线程不安全,推荐多线程用 strtok_r()。

1、strtok() 函数的作用

strtok() 是 C 标准库中的字符串分割函数,功能是将字符串按照指定的分隔符切割成一个个“token(子串)”。函数原型(在 中)。

char *strtok(char *str, const char *delim);

str 首次调用时传入要分割的字符串,后续传入 NULL 继续分割。

delim 分隔符字符串(可包含多个字符,如 ",. "

2、工作原理(核心机制)

第一次调用,strtok(str, delim) 修改 str,将第一个 token 末尾的分隔符 '\0' 替换(直接破坏原字符串)。

返回第一个 token。后续调用,strtok(NULL, delim)从上次位置继续,返回下一个 token。没有更多 token 后,返回 NULL

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

int main() {
    char str[] = "Hello,World,This,is,C";
    char *token = strtok(str, ",");

    while (token != NULL) {
        printf("%s\n", token);
        token = strtok(NULL, ",");  // 继续提取下一个
    }

    return 0;
}

注意:

strtok() 会在分隔符位置写入 '\0',原字符串会被修改。所以不能多线程安全,多线程用 strtok_r()。只有第一次传字符串地址,后续传 NULL。不能在同一线程里同时嵌套使用多个 strtok(),因为共用内部状态。

3、strtok_r()(线程安全版本)

strtok_r()strtok() 的线程安全版本,用于在 C 语言中按指定分隔符分割字符串。它避免了 strtok() 使用全局静态指针的问题,可以多个线程或多个字符串同时安全地进行分割操作。

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

saveptr 用于保存分割状态,适合多线程或递归中安全使用。

#include <stdio.h>
int main() {
  char str[] = "Hello,World,This,is,C";
  char *saveptr;
  char *token = strtok_r(str, ",", &saveptr);
  while (token != NULL) {
      printf("%s\n", token);
      token = strtok_r(NULL, ",", &saveptr);
  }
  return 0;
}

4、使用场景

strtok() 函数常用于字符串分割,可以于解析CSV数据,命令行参数解析,配置文件读取,URL、路径、版本号拆分,网络协议数据解析(如HTTP头)等。

1)处理CSV格式数据

#include <stdio.h>
int main() {
  char str[] = "apple,banana,orange";
  char *token = strtok(str, ",");
  while (token != NULL) {
      printf("%s\n", token);
      token = strtok(NULL, ",");
  }
  return 0;
}

2)命令行输入解析

#include <stdio.h>
int main() {
  char input[] = "copy file1.txt file2.txt";
  char *token = strtok(input, " ");
  while (token != NULL) {
      printf("Token: %s\n", token);
      token = strtok(NULL, " ");
  }

  return 0;
}

3)解析配置文件

#include <stdio.h>
int main() {
  char line[] = "key1=value1";
  char *key = strtok(line, "=");
  char *value = strtok(NULL, "=");
  printf("key=%s, value=%s\n", key, value);
  
  return 0;
}

4)处理URL、路径或版本号等结构

#include <stdio.h>
int main() {
  char url[] = "http://www.example.com/index.html";
  char *token = strtok(url, "/");
  while (token != NULL) {
      printf("%s\n", token);
      token = strtok(NULL, "/");
  }
  return 0;
}

推荐文档