非常教程

C参考手册

字符串 | Strings

strtok_s

在头文件<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)在由str指向的以空字符结尾的字节字符串中查找下一个标记。 分隔符字符由delim指向的以空字符结尾的字节字符串标识。

该函数被设计为被称为倍数时间以从相同的字符串获得连续的令牌。

  • 如果str!= NULL,则该调用被视为针对此特定字符串的第一次调用strtok。该函数搜索不在delim中的第一个字符。
  • 如果没有找到这样的字符,那么str中就没有令牌了,并且该函数返回一个空指针。
  • 如果找到这样的字符,它就是令牌的开始。然后该函数从此处开始搜索包含在delim中的第一个字符。

如果没有找到这样的字符,str只有一个标记,未来对strtok的调用将返回一个空指针

如果找到这样的字符,它将被替换为空字符'\ 0',并且指向以下字符的指针将存储在静态位置以供后续调用。

  • 该函数然后将指针返回到令牌的开始处
  • 如果str == NULL,则该调用将被视为对strtok的后续调用:该函数将继续前一次调用中的离开。行为与先前存储的指针作为str传递的行为相同。

如果str或delim不是指向以空字符结尾的字节字符串的指针,则行为未定义。

2)与(1)相同,除了在每一步中,将留在str中的字符数写入* strmax并将标记器的内部状态写入* ptr。 重复调用(使用null str)必须将strmax和ptr与先前调用所存储的值一起传递。 此外,在运行时检测到以下错误,并调用当前安装的约束处理函数,而不在ptr指向的对象中存储任何内容

  • strmaxdelim或者ptr是空指针
  • 在非初始调用(带有空值str)上,*ptr是一个空指针
  • 在第一次通话时,*strmax是零或大于RSIZE_MAX
  • 搜索令牌的末尾到达源字符串的末尾(如初始值所测量的那样*strmax)),而不会遇到空终止符

如果两个str都指向缺少空字符的字符数组,并且strmax指向的值大于该字符数组的大小,则行为是未定义的。 作为所有边界检查函数,只有当__STDC_LIB_EXT1__由实现定义并且用户在包含string.h之前将__STDC_WANT_LIB_EXT1__定义为整数常量1时,strtok_s才能保证可用。

参数

str

-

指向以空字符结尾的字节字符串进行标记的指针

DELIM

-

指向标识分隔符的以空字符结尾的字节串的指针

strmax

-

指向最初保存str大小的对象的指针:strtok_s存储待检查的字符数

PTR

-

指向char *类型的对象的指针,strtok_s用它来存储它的内部状态

返回值

返回指向下一个标记开头的指针,如果没有其他标记,则返回NULL。

注意

这个函数具有破坏性:它在字符串str的元素中写入'\ 0'字符。 特别是,字符串文字不能用作strtok的第一个参数。

每次调用strtok都会修改一个静态变量:不是线程安全的。

与大多数其他标记器不同,strtok中的分隔符对于每个后续标记都可能不同,甚至可能取决于先前标记的内容。

strtok_s函数不同于POSIX strtok_r函数,通过防止存储在被标记化的字符串之外,并通过检查运行时约束。

#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#include <stdio.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] ? printf("%c", input[n]) : printf("\\0");
    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] ? printf("%c", str[n]) : printf("\\0");
    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'

参考

  • 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函数

扩展内容

strpbrk

找到一个字符串中任何字符的第一个位置,另一个字符串(函数)

strcspn

返回最大初始段的长度,该最大初始段只包含在另一个字节字符串中找不到的字符(函数)

strspn

返回仅由另一个字节字符串(函数)中的字符组成的最大初始段的长度

wcstokwcstok_s(C95)(C11)

在宽字符串(函数)中查找下一个标记

| 用于strtok 的C ++文档|

C

C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。