【问题标题】:What's the difference between strtok and strtok_r in C?C中的strtok和strtok_r有什么区别?
【发布时间】:2014-04-08 06:23:12
【问题描述】:

C 中的strtokstrtok_r 有什么区别,我们应该什么时候使用哪个?

【问题讨论】:

  • 一个是可重入的,另一个不是。我认为手册说明了这一点。
  • 不是标准 C,它是 Posix。 Strtok() 是一个错误工厂,它使用 CRT 内部的全局变量来跟踪字符串位置。所以你不能同时在多个字符串上使用它。线程也有风险,大多数 CRT 确实解决了这个问题。
  • 为了更迷惑你,C11 加了strtok_s

标签: c strtok


【解决方案1】:

strtok 等价于(通常定义为):

char *strtok(char *str, const char *delim) {
    static char *save;
    return strtok_r(str, delim, &save);
}

一般来说,您应该直接使用strtok_r 而不是strtok,除非您需要将您的代码移植到仅支持strtok 的pre-POSIX-2001 系统中

【讨论】:

    【解决方案2】:

    _r 版本的函数是可重入的:您可以从多个线程同时调用它们,或者在嵌套循环中调用它们,等等。可重入版本通常需要一个额外的参数,该参数用于存储调用之间的状态,而不是使用全局变量。

    不可重入版本通常使用全局状态,因此如果您从多个线程调用它们,您可能会调用未定义的行为。您的程序可能会崩溃,甚至更糟。

    来自手册页 (man 3 strtok):

    strtok_r() 函数是strtok() 的可重入版本。上下文 每次调用都必须提供指针 last。 strtok_r() 函数可以 也可用于将两个解析循环相互嵌套,只要 使用了单独的上下文指针。

    【讨论】:

    • 是否有这样的 _r 函数与我可能在不知道的情况下使用的原始函数的列表?由于 _r 不是标准 C 我不能只在 *.h 中为它们 grep
    • @dargaud:它们*.h 文件中。这些函数不是“标准 C”,但它们是 POSIX 标准的一部分。我唯一能想到的另一个是strerror_r
    【解决方案3】:

    strtok保存静态指针以备下次重用,当你给NULL作为第一个参数时,你就不能并行解析2个字符串。

    strtok_r 中,您还给出了指针,作为输出参数(指向指针的指针)。所以函数中没有静态指针,您可以从一个字符串移动到另一个字符串并返回...

    【讨论】:

      【解决方案4】:

      根据文档,strtok_r() 函数是 strtok() 的可重入版本。

      char *strtok_r(char *s1, const char *s2, char **s3);
      

      它从字符串 s1 中获取下一个标记,其中标记是由 s2 中的字符分隔的字符串。为了从 s1 中获取第一个令牌,调用 strtok_r() 并将 s1 作为其第一个参数。来自 s1 的剩余标记是通过调用 strtok_r() 获得的,第一个参数为空指针。分隔符字符串 s2 可能因调用而异。

      【讨论】:

        猜你喜欢
        • 2012-02-19
        • 2021-07-31
        • 1970-01-01
        • 2014-03-01
        • 2011-04-05
        • 2011-10-18
        • 1970-01-01
        相关资源
        最近更新 更多