在 C 語言開發中,字符串分割是高頻需求:解析配置文件、處理 CSV 數據、命令行參數拆分等。很多開發者(包括早期的我)習慣手寫解析邏輯,不僅繁瑣易錯,還難以應對多層分割場景。C 標準庫提供的 strtok 和 strtok_r 才是正解。
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 內部使用靜態變量保存分割狀態,導致:
char *strtok_r(char *str, const char *delim, char **saveptr);
saveptr:用戶提供的指針,用於保存分割狀態,替代靜態變量。saveptr 即可實現嵌套分割。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"。strtok_r 是 POSIX 標準,Windows 下對應 strtok_s。| 場景 | 推薦函數 |
|---|---|
| 單線程、單層分割 | strtok |
| 多線程、或需嵌套分割 | strtok_r / strtok_s |
| 不想修改原字符串 | 手寫解析 / strchr + strncpy |
掌握 strtok/strtok_r 能大幅簡化文本處理代碼。記住:用字符數組、傳 NULL 續分、嵌套用 _r 版本,即可避開 90% 的坑。