C strtok如何存储字符串参数之外的内容?

C strtok如何存储字符串参数之外的内容?,c,strtok,c11,C,Strtok,C11,strtok_s函数(C11)解决的两个问题之一是它防止存储在输入字符串之外。据我所知,只有将以非空结尾的字符串传递给strtok,这才可能实现 如果我只将正确的以null结尾的字符串传递给strtok,那么就没有在输入字符串之外写入的风险,这是正确的吗?让我们开始回答主要问题,关于strtok写入超过包含字符串的缓冲区的大小 strtok实际上修改了输入字符串:它在过去使用分隔符的位置写入一个字符串终止符('\0')。通过这种方式,它可以将以null结尾的令牌返回给用户 如果提供了错误输入(字

strtok_s
函数(C11)解决的两个问题之一是它防止存储在输入字符串之外。据我所知,只有将以非空结尾的字符串传递给strtok,这才可能实现


如果我只将正确的以null结尾的字符串传递给
strtok
,那么就没有在输入字符串之外写入的风险,这是正确的吗?

让我们开始回答主要问题,关于
strtok
写入超过包含字符串的缓冲区的大小

  • strtok
    实际上修改了输入字符串:它在过去使用分隔符的位置写入一个字符串终止符(
    '\0'
    )。通过这种方式,它可以将以null结尾的令牌返回给用户
  • 如果提供了错误输入(字符串终止符缺失的缓冲区),则它可能会写入超过输入缓冲区大小的内容。它将一直读取,直到在内存中找到
    '\0'
    ,如果在到达末尾之前找到分隔符,则写入数据

  • 现在,我们不能正确地说“
    strtok_s
    阻止存储在输入字符串之外”,但我们可以说,该函数提供了一种方法来控制检查的输入字符串的字节数,并因此写入(如上所述)

    我们正在讨论的控件与使用
    strncpy
    而不是
    strcpy
    时的控件相同:如果输入字符串在缺少字符串终止符的情况下避免内存损坏,我们可以将最大大小传递给
    strtok_s

    让我们看看签名:

    char *strtok_s(char *restrict str, rsize_t *restrict strmax,
                   const char *restrict delim, char **restrict ptr);
    
    与strtok的接口相比,我们还有两个参数。
    ptr
    参数有助于使其可重入,它也出现在
    strtok\u r
    中。这与这个问题没有直接关系

    strmax
    参数就是我们正在查找的参数

    strmax-指向一个对象的指针,该对象最初包含str的大小:strtok_s存储有待检查的字符数

    (重点是我的)


    因此,将指向使用包含输入字符串的字符缓冲区大小初始化的变量的指针传递给
    strmax
    ,将确保永远不会发生超过该大小的写入操作。

    如果不是这样,该函数将不会包含在C标准中。“…它在外部写入的风险…”你是想问一下在外面读书的事吗
    strtok
    根本不做任何写入操作,即使在输入字符串中也是如此。@arthurtaca您错了。函数会更改输入字符串。@vladfromsoops你是对的,我错了。很抱歉造成混淆。请在使用任何可选的附录K函数之前阅读,因为它们不会真正使您的代码更安全。请特别注意这一部分:“由于与规范的大量偏差,Microsoft实现不能被视为符合规范或可移植。”这就是我所想的。
    strmax
    参数实质上扩展了
    strtok
    以允许任意字符数组作为输入,而不仅仅是以null结尾的字符串。@cholz I还进行了编辑以直接回答标题问题