Существует еще одна причина не использовать оригинальную функцию семейства strtok :
[...] Однако в одном потоке чередование вызовов одной из этих функций может привести к повреждению данных и неточным результатам . При разборе различных строк завершите анализ одной строки, прежде чем начинать анализировать следующую. Также помните о потенциальной опасности при вызове одной из этих функций из цикла, где вызывается другая функция. Если другая функция в конечном итоге использует одну из этих функций, в результате чередуется последовательность вызовов, что приводит к повреждению данных.
Причина в том, что strtok
не является реентерабельным: считалось, что при его разработке было бы неплохо использовать глобальную переменную в качестве хранилища для контекста (как вы думаете, strtok
может вспомнить, куда продолжить между каждым вызовом функции?).
Прошлое - это прошлое, и мы не должны судить о коде десятилетия назад, но потом, со всеми новыми стандартами (C99 приходит на ум), я все еще удивлен, что эта функция не подверглась рефакторингу.
По крайней мере, семейство функций strtok_s , созданное Microsoft, использует для этого предоставленную пользователем переменную (называемую context
). Если у вас есть выбор, для производственного кода используйте strtok_s
.
И если вам нужно предоставить кроссплатформенный код, мой совет:
- написать функцию, которая будет использоваться как косвенная для реальной
- В Windows перенаправить на strtok_s
- На любой платформе, где есть безопасный strtok (я нашел
strtok_r
при поиске в Google), перенаправьте на эту функцию
- На платформах, где нет безопасного strtok, пишите свои собственные (это совсем не сложно, и это хорошее упражнение для изучения программирования)
Теперь есть альтернативы C ++ этим функциям C, которые либо комбинируют std::string
методы вместе, либо используют boost :: tokenizer