首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言字符串分割利器:strtok 與 strtok_r 深度解析

     編輯:關於C語言

C語言字符串分割利器:strtok 與 strtok_r 深度解析

在 C 語言開發中,字符串分割是高頻需求:解析配置文件、處理 CSV 數據、命令行參數拆分等。很多開發者(包括早期的我)習慣手寫解析邏輯,不僅繁瑣易錯,還難以應對多層分割場景。C 標準庫提供的 strtok 和 strtok_r 才是正解。

strtok 基本用法

char *strtok(char *str, const char *delim);
  • 首次調用:str 指向待分割字符串,delim 為分隔符集合。返回第一個 token 指針。
  • 後續調用:str 傳 NULL,函數從上次位置繼續搜索。
  • 返回 NULL 表示分割結束。

示例:單層分割

char str[] = "now # is the time for all # good men to come to the # aid of their country";
char delims[] = "#";
char *token = strtok(str, delims);
while (token != NULL) {
    printf("token: \"%s\"\n", token);
    token = strtok(NULL, delims);
}

輸出:

token: "now "
token: " is the time for all "
token: " good men to come to the "
token: " aid of their country"

strtok 的致命弱點:非線程安全、不可嵌套

strtok 內部使用靜態變量保存分割狀態,導致:

  1. 多線程環境下數據競爭。
  2. 無法在外層循環分割的同時進行內層分割(如先按逗號分割,再按空格分割每個字段)。

strtok_r:可重入、線程安全的替代方案

char *strtok_r(char *str, const char *delim, char **saveptr);
  • saveptr:用戶提供的指針,用於保存分割狀態,替代靜態變量。
  • 每次調用傳入同一 saveptr 即可實現嵌套分割。

示例:多層分割(解析 "Fred male 25,John male 62")

char buf[] = "Fred male 25,John male 62,Anna female 16";
char *outer_ptr = NULL, *inner_ptr = NULL;
char *field = strtok_r(buf, ",", &outer_ptr);
while (field) {
    char *sub = strtok_r(field, " ", &inner_ptr);
    while (sub) {
        printf("sub-token: %s\n", sub);
        sub = strtok_r(NULL, " ", &inner_ptr);
    }
    field = strtok_r(NULL, ",", &outer_ptr);
}

重要注意事項

  • 修改原字符串:兩個函數都會在原字符串中插入 \0 截斷 token,因此不能用於字符串字面量(如 char *s = "a,b,c"),必須用字符數組 char s[] = "a,b,c"。
  • 連續分隔符:會被視為一個分隔邊界,不會產生空 token。
  • 線程安全:strtok_r 是 POSIX 標準,Windows 下對應 strtok_s。

適用場景對比

場景推薦函數
單線程、單層分割strtok
多線程、或需嵌套分割strtok_r / strtok_s
不想修改原字符串手寫解析 / strchr + strncpy

總結

掌握 strtok/strtok_r 能大幅簡化文本處理代碼。記住:用字符數組、傳 NULL 續分、嵌套用 _r 版本,即可避開 90% 的坑。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved