strtok, strtok_s
來自 cppreference.com
定義於標頭檔案 <string.h> |
||
(1) | ||
char* strtok( char* str, const char* delim ); |
(直到 C99) | |
char* strtok( char* restrict str, const char* restrict delim ); |
(C99 起) | |
char* strtok_s( char* restrict str, rsize_t* restrict strmax, const char* restrict delim, char** restrict ptr ); |
(2) | (C11 起) |
標記化一個以空字元結尾的位元組字串。
1) 對
strtok
的一系列呼叫會將 str 所指向的字串分解為一系列標記,每個標記都由 delim 所指向的字串中的一個字元定界。序列中的每次呼叫都有一個搜尋目標- 如果 str 非空,則該呼叫是序列中的首次呼叫。搜尋目標是 str 所指向的以空字元結尾的位元組字串。
- 如果 str 為空,則該呼叫是序列中的後續呼叫之一。搜尋目標由序列中的上一次呼叫決定。
序列中的每次呼叫都會在搜尋目標中查詢第一個不包含在 delim 所指向的分隔符字串中的字元,分隔符字串可以在每次呼叫中不同。
如果 str 或 delim 不是指向以空字元結尾的位元組字串的指標,則行為未定義。
2) 與 (1) 相同,但有以下不同之處
- 在每次呼叫中,將 str 中剩餘的字元數寫入 *strmax,並將標記器的內部狀態寫入 *ptr。
- 序列中的後續呼叫必須傳入具有上一次呼叫儲存的值的 strmax 和 ptr。
- 以下錯誤會在執行時檢測到,並呼叫當前安裝的約束處理函式,而不將任何內容儲存到 ptr 所指向的物件中
- strmax、delim 或 ptr 為空指標。
- 對於序列中的後續呼叫,*ptr 為空指標。
- *strmax 大於 RSIZE_MAX。
- 找到的標記末尾未出現在搜尋目標的前 *s1max 個字元內。
如果 str 指向的字元陣列缺少空字元,且 strmax 指向的值大於該字元陣列的大小,則行為未定義。
與所有邊界檢查函式一樣,只有當實現定義了 __STDC_LIB_EXT1__ 並且使用者在包含 <string.h> 之前將 __STDC_WANT_LIB_EXT1__ 定義為整數常量 1 時,才保證
strtok_s
可用。目錄 |
[編輯] 引數
str | - | 指向要標記化的以空字元結尾的位元組字串的指標 |
delim | - | 指向標識分隔符的以空字元結尾的位元組字串的指標 |
strmax | - | 指向最初儲存 str 大小的物件的指標:strtok_s 儲存剩餘要檢查的字元數 |
ptr | - | 指向 char* 型別物件的指標,strtok_s 用它來儲存其內部狀態 |
[編輯] 返回值
1) 返回指向下一個標記的第一個字元的指標,如果沒有標記則返回空指標。
2) 返回指向下一個標記的第一個字元的指標,如果沒有標記或存在執行時約束違規則返回空指標。
[編輯] 注意
此函式具有破壞性:它在字串 str 的元素中寫入 '\0' 字元。特別是,字串字面量不能用作 strtok
的第一個引數。
每次呼叫 strtok
都會修改一個靜態變數:它不是執行緒安全的。
與大多數其他標記器不同,strtok
中的分隔符對於每個後續標記可以不同,甚至可以取決於前一個標記的內容。
strtok_s
函式與 POSIX strtok_r
函式的不同之處在於,它透過防止在被標記化的字串外部儲存來防止溢位,並檢查執行時約束。Microsoft CRT strtok_s
簽名與此 POSIX strtok_r
定義匹配,而不是 C11 strtok_s
。
[編輯] 示例
執行此程式碼
#define __STDC_WANT_LIB_EXT1__ 1 #include <stdio.h> #include <string.h> int main(void) { char input[] = "A bird came down the walk"; printf("Parsing the input string '%s'\n", input); char* token = strtok(input, " "); while (token) { puts(token); token = strtok(NULL, " "); } printf("Contents of the input string now: '"); for (size_t n = 0; n < sizeof input; ++n) input[n] ? putchar(input[n]) : fputs("\\0", stdout); puts("'"); #ifdef __STDC_LIB_EXT1__ char str[] = "A bird came down the walk"; rsize_t strmax = sizeof str; const char* delim = " "; char* next_token; printf("Parsing the input string '%s'\n", str); token = strtok_s(str, &strmax, delim, &next_token); while (token) { puts(token); token = strtok_s(NULL, &strmax, delim, &next_token); } printf("Contents of the input string now: '"); for (size_t n = 0; n < sizeof str; ++n) str[n] ? putchar(str[n]) : fputs("\\0", stdout); puts("'"); #endif }
可能的輸出
Parsing the input string 'A bird came down the walk' A bird came down the walk Contents of the input string now: 'A\0bird\0came\0down\0the\0walk\0' Parsing the input string 'A bird came down the walk' A bird came down the walk Contents of the input string now: 'A\0bird\0came\0down\0the\0walk\0'
[編輯] 參考資料
- C23 標準 (ISO/IEC 9899:2024)
- 7.24.5.8 strtok 函式 (p: TBD)
- K.3.7.3.1 strtok_s 函式 (p: TBD)
- C17 標準 (ISO/IEC 9899:2018)
- 7.24.5.8 strtok 函式 (p: TBD)
- K.3.7.3.1 strtok_s 函式 (p: TBD)
- C11 標準 (ISO/IEC 9899:2011)
- 7.24.5.8 strtok 函式 (p: 369-370)
- K.3.7.3.1 strtok_s 函式 (p: 620-621)
- C99 標準 (ISO/IEC 9899:1999)
- 7.21.5.8 strtok 函式 (p: 332-333)
- C89/C90 標準 (ISO/IEC 9899:1990)
- 4.11.5.8 strtok 函式
[編輯] 另請參閱
在一個字串中查詢另一個字串中任意字元的第一個位置 (函式) | |
返回由另一個位元組字串中找到的字元組成的最大初始段的長度 僅由另一個位元組字串中未找到的字元組成 (函式) | |
返回由另一個位元組字串中找到的字元組成的最大初始段的長度 的字元 (函式) | |
(C95)(C11) |
在寬字串中查詢下一個標記 (函式) |
C++ 文件 用於 strtok
|