Почему strtok () должен быть устаревшим?

Я слышу это от многих программистов, что использование strtok, возможно, устарело в ближайшем будущем. Некоторые говорят, что все еще. Почему это плохой выбор? strtok () отлично работает при токенизации данной строки. Имеет ли это отношение к пространственно-временным сложностям? Лучшая ссылка, которую я нашел в интернете, была этой. Но это, кажется, не решает моего любопытства. Предложите любые альтернативы, если это возможно.

2 ответов


почему это плохой выбор?

основной метод решения задач с помощью программирования состоит в том, чтобы построить абстракции что можно использовать надежно для решения подзадач, а затем compose решения этих подзадач в решения более крупных проблем.

поведение strtok работает непосредственно против этих целей различными способами; это плохая абстракция, которая ненадежна, потому что она сочиняет плохо.

фундаментальная проблема токенизации:учитывая позицию в строке, дайте позицию конца маркера, начинающегося в этой позиции. Если бы стрток сделал только это, это было бы здорово. Он будет иметь четкую абстракцию, он не будет полагаться на скрытое глобальное состояние, он не будет изменять свои входные данные.

чтобы увидеть ограничения strtok, представьте себе попытку токенизировать язык, где мы хотим разделить токены пробелами, если токен заключено в " ", в этом случае мы хотим применить другое правило токенизации к содержимому цитируемой области, а затем забрать правило разделения пространства после. strtok очень плохо сочиняет сам с собой и поэтому полезен только для самых тривиальных задач токенизации.

имеет ли это какое-либо отношение к пространственно-временным сложностям?

нет.

предложить любые альтернативы, если вероятный.

лексеры не трудно написать; просто напишите один!

бонусные баллы, если вы пишете неизменяемые лексер. Неизменяемый лексер-это небольшая структура, содержащая ссылку на лексируемую строку, текущую позицию лексера и любое состояние, необходимое лексеру. Чтобы извлечь токен, вы вызываете метод "next token", передаете лексер и возвращаете токен и новый лексер. Затем новый лексер можно использовать для lex далее токен, и вы отбрасываете предыдущий лексер, если хотите.

неизменяемый метод лексера легче рассуждать, чем лексеры, которые изменяют состояние. И вы можете отладить их, сохранив отброшенные лексеры в списке, и теперь у вас есть полная история операций токенизации, открытых для проверки сразу.


ограничение strtok(char *str, const char *delim) заключается в том, что он не может работать на нескольких строках одновременно, поскольку он поддерживает статический указатель для хранения индекса до его анализа (следовательно, достаточно, если играть только с одной строкой за раз). Лучший и безопасный метод-использовать strtok_r(char *str, const char *delim, char **saveptr) который явно принимает третий указатель для сохранения проанализированного индекса.