当前位置: C语言 -- 附录 -- strtok_s

strtok_s函数


概要:
#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
char *strtok_s(char * restrict s1,
      rsize_t * restrict s1max,
      const char * restrict s2,
      char ** restrict ptr);

描述:

该函数拆分参数s1指向的字符串。连续调用该函数将参数s1指向的字符串拆分为一系列标记,每个标记使用参数s2指向字符串中的字符进行分隔。参数ptr指向调用者提供的char类型指针,strtok_s函数在该指针中存储继续扫描相同字符串所需的信息。

第一次调用该函数,参数s1为非空指针,参数s1max指向对象的值为参数s1指向数组的元素数,函数将向参数ptr指向的对象中存入一个初始值,并更新参数s1max指向的值,以反映与参数ptr相关的元素数量。随后调用该函数,第一个参数为空指针,参数s1max和参数ptr指向的对象要求具有上次调用的结果,然后更新。参数s2指向的分隔字符串每次调用时可以不相同。

第一次调用strtok_s函数将搜索参数s1指向字符串中的第一个非分隔字符(即不是参数s2指向字符串中的字符。)。如果不存在这样的字符,参数s1指向的字符串不存在标记,函数返回空指针;如果存在这样的字符,该字符是第一个标记的开始字符,函数从这里开始搜索当前分隔字符。如果未搜索到当前分隔字符,当前标记将扩展至参数s1指向字符串的末尾,随后在相同字符串中搜索标记将返回空指针。如果搜索到当前分隔字符,该字符将被一个空字符覆盖,当前标记结束。

所有情况下,函数都会在参数ptr指向的指针中存储足够的信息,以便后续调用(参数s1为空指针,参数ptr为未修改的指针值。)从刚刚超过被空字符覆盖的元素(如果有)开始搜索。


运行约束:

参数s1max、参数s2和参数ptr不能是空指针。如果参数s1是空指针,*ptr不能是空指针。*s1max的值应不大于宏RSIZE_MAX。第一次调用strtok_s函数,发现的标记的末尾应在参数s1指向字符串的前*s1max个字符内;后续调用strtok_s函数,发现的标记的末尾应在第一个*s1max个字符内。

如果存在运行约束冲突,函数不会通过参数s1或者参数s2间接执行,也不会向参数ptr指向的对象中存储值。


参数:
char * restrict s1

指向字符串的指针。

rsize_t * restrict s1max

参数s1指向数组的元素数。

const char * restrict s2

指向分隔字符串的指针。

char ** restrict ptr

指针,指向对象存储继续扫描相同字符串所需的信息。


返回值:

如果没有标记或者存在运行约束冲突,函数返回空指针;否则函数返回指向标记首字符的指针。


范例:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
/*安全函数strtok_s范例*/

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <string.h>

int main(void)
{
    char str[] = "You can fool all the people some of the time,\
                and some of the people all the time,\
                but you can not fool all the people all the time.";
    const char delimiter[] = ",.\' \"?!";
    char *pch;
    char *nextToken;
    int count = 0;  
    
    /*统计句子中的单词数。*/
    pch = strtok_s(str, delimiter, &nextToken);
    
    while(pch != NULL)
    {
        ++count;
        pch = strtok_s(NULL, delimiter, &nextToken);
    }
    
    printf_s("Total %d word%s.\n", count, (count>1)?"s":"");
    
    return 0;
}


输出:

Total 29 words.

注:使用Visual Studio编译。

strtok_s函数在Visual Studio中的声明与ISO/IEC 9899:2018标准有差异,在Visual Studio中声明如下:

char *strtok_s(
   char *strToken, 
   const char *strDelimit,
   char **context);

strToken: 含有标记的字符串。

strDelimit: 分隔字符集。

context: 存储位置信息的指针。

Visual Studio中,没有ISO/IEC 9899:2018标准中的第二个参数。


相关内容:
strtok 拆分字符串的函数。