Я слышал от многих программистов, что использование strtok может быть устарело в ближайшем будущем. Некоторые говорят, что это все еще. Почему это плохой выбор? strtok() отлично работает в токенизации данной строки. Нужно ли что-то делать с сложностями времени и пространства? Лучшая ссылка, которую я нашел в Интернете, была this. Но это не похоже на мою любознательность. Предложите любые альтернативы, если это возможно.
Почему strtok() не рекомендуется?
Ответ 1
Почему это плохой выбор?
Основным методом решения задач путем программирования является построение абстракций, которые могут быть надежно использованы для решения подзадач, а затем составляют решения этих подзадач в решениях более крупных задач.
strtok поведение работает прямо против этих целей различными способами; это плохая абстракция, которая ненадежна, потому что она плохо сочиняется.
Основная проблема токенизации: если задана позиция в строке, укажите позицию конца токена, начинающегося в этой позиции. Если бы strtok сделал только это, было бы здорово. Он будет иметь четкую абстракцию, он не будет полагаться на скрытое глобальное состояние, он не будет изменять свои входы.
Чтобы увидеть ограничения strtok, представьте, что пытаетесь проклинать язык, где мы хотим разделить токены пробелами, если токен не заключен в "
"
, и в этом случае мы хотим применить другое правило токенизации для содержимое указанной области, а затем забрать с помощью правила разделения пространства после. strtok очень плохо сочиняет себя и поэтому полезен только для самых тривиальных задач токенизации.
Нужно ли что-либо делать с сложностями времени и пространства?
Нет.
Предложите любые альтернативы, если это возможно.
Лексерам не сложно писать; просто напишите!
Бонусные баллы, если вы пишете неизменяемый лексер. Необязательный лексер - это небольшая структура, содержащая ссылку на строку lexed, текущую позицию лексера и любое состояние, необходимое лексеру. Чтобы извлечь токен, вы вызываете метод "следующий токен", переходите в лексер, и вы возвращаете токен и новый лексер. Новый лексер можно затем использовать для lex следующего токена, и вы отбросите предыдущий лексер, если хотите.
Необязательный лексерский метод легче рассуждать, чем лексеры, которые изменяют состояние. И вы можете отлаживать их, сохраняя отброшенные лексеры в списке, и теперь у вас есть полная история операций по токенизации, открытая для проверки сразу.
Ответ 2
Ограничение strtok(char *str, const char *delim)
заключается в том, что он не может работать с несколькими строками одновременно, поскольку он поддерживает статический указатель для хранения индекса до его разбора (следовательно, он достаточен для воспроизведения только по одной строке за раз). Лучше и безопаснее использовать strtok_r(char *str, const char *delim, char **saveptr)
, который явно принимает третий указатель, чтобы сохранить анализируемый индекс.