strtok:傳統標準庫函數
函數原型
#include <string.h>
char *strtok(char *str, const char *delim);
特性
- 破壞原字串:將分隔符替換為
\0。
- 非執行緒安全:內部靜態指標記錄位置,多執行緒同時呼叫會互相干擾。
- 首次呼叫 傳入字串指標,後續呼叫傳
NULL。
- 連續分隔符視為一個:
"a,,b" 以 "," 分割僅得 "a", "b"。
範例
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"
*/
strsep:BSD/GNU 擴充,Linux 標準
函數原型
#include <string.h>
char *strsep(char **stringp, const char *delim);
特性
- 不修改原字串指標:透過
**stringp 更新位置。
- 執行緒安全:無靜態狀態。
- 保留空欄位:
"a,,b" 分割得 "a", "", "b"。
- Windows (MSVC) 無此函數,需自行實作或使用
strtok_s。
範例
char str[] = "2011/11/28";
char *p = str;
char *token;
while ((token = strsep(&p, "/")) != NULL) {
printf("%s\n", token);
}
/* 輸出:
2011
11
28
*/
兩者差異總結表
| 特性 | strtok | strsep |
| 標準 | C89/C99 | POSIX.1-2001 / BSD / GNU |
| Windows 支援 | 是 | 否 (MSVC) |
| 執行緒安全 | 否 | 是 |
| 空欄位處理 | 略過 | 保留 |
| 修改原字串 | 是 | 是 (將分隔符改 \0) |
| 多重分隔符 | 支援字串集合 | 支援字串集合 |
Windows 替代方案
strtok_s (C11 Annex K / MSVC):執行緒安全版 strtok,需 context 參數。
- 自行實作
strsep:
char *my_strsep(char **sp, const char *delim) {
char *p, *s;
if (sp == NULL || *sp == NULL) return NULL;
s = *sp;
p = s + strcspn(s, delim);
if (*p != '\0') *p++ = '\0';
*sp = p;
return s;
}
建議選擇指南
- 跨平台專案、Linux 環境 → strsep(保留空欄位、執行緒安全)。
- Windows 專案、需相容舊代碼 → strtok_s 或 strtok(注意多執行緒)。
- 簡單單執行緒解析、不介意空欄位略過 → strtok 最簡潔。