为什么要弃用strtok()?

我从很多程序员那里听到,strtok的使用可能在不久的将来被弃用。 有人说它还在。 为什么这是一个糟糕的选择? strtok()在标记给定字符串时效果很好。 它是否必须对时间和空间的复杂性做任何事情? 我在互联网上找到的最佳链接就是这个 。 但这似乎并没有解决我的好奇心。 如果可能,建议任何替代方案。

为什么这是一个糟糕的选择?

通过编程解决问题的基本技术是构造可以可靠地用于解决子问题的抽象 ,然后将这些子问题的解决方案组合成更大问题的解决方案。

strtok的行为以各种方式直接反对这些目标; 这是一个糟糕的抽象,不可靠,因为它组成很差。

标记化的基本问题是: 给定字符串中的位置,给出从该位置开始的标记结尾的位置 。 如果strtok只这样做,那就太好了。 它会有一个明确的抽象,它不会依赖隐藏的全局状态,也不会修改它的输入。

要查看strtok的局限性,想象一下我们希望用空格分隔标记的语言,除非标记用" "括起来,在这种情况下我们希望对引用区域的内容应用不同的标记化规则,然后拿起空间分隔规则。 strtok与自身组合很差,因此仅对最琐碎的标记化任务有用。

它是否必须对时间和空间的复杂性做任何事情?

没有。

如果可能,建议任何替代方案。

词典并不难写; 只写一个!

如果你写一个不可变的词法分析器,奖励积分。 不可变词法分析器是一个小结构,它包含对词法的引用,词法分析器的当前位置以及词法分析器所需的任何状态。 要提取令牌,您可以调用“下一个令牌”方法,传入词法分析器,然后返回令牌和新词法分析器 。 然后可以使用新的词法分析器来表示下一个标记,如果您愿意,可以丢弃之前的词法分析器。

不可变词法分析器技术比修改状态的词法分析器更容易推理。 您可以通过将丢弃的词法分析器保存在列表中来调试它们,现在您可以立即打开令牌化操作的完整历史记录。

strtok(char *str, const char *delim)是它不能同时处理多个字符串,因为它维护一个静态指针来存储索引,直到它被解析为止(因此如果在一个字符串中只播放一个字符串就足够了)时间)。 更好更安全的方法是使用strtok_r(char *str, const char *delim, char **saveptr) ,它显式地使用第三个指针来保存解析的索引。