为什么要弃用strtok()?

Vid*_*rom 13 c token strtok

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

Eri*_*ert 18

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

用于通过编程解决问题的根本技术是构建抽象其可用于可靠地解决的子问题,然后撰写解决这些子问题入到更大的问题的解决方案.

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

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

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

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

没有.

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

Lexers并不难写; 只写一个!

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

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

  • @jamesdlin:我鼓励你写一个你更喜欢的答案,我们都可以从你的见解中受益. (2认同)

Sha*_*mar 13

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

  • 换句话说,它以多种方式糟透了:) (4认同)
  • 换句话说,它本质上不仅修改了[全局状态](https://softwareengineering.stackexchange.com/questions/148108/why-is-global-state-so-evil),而是*隐藏的*全局状态! (3认同)
  • 换句话说 - 它不是线程安全的:(( (3认同)
  • 换句话说,它不是可重入的. (3认同)