Quelle est la différence entre strtok_r et strtok_s dans C?

J’essaie d’utiliser cette fonction dans un programme C qui doit pouvoir être compilé sous Linux et Windows. Au début, j’ai essayé d’utiliser strtok_r, mais quand j’ai compilé sur Windows, il s’est plaint de l’absence de la fonction et a dit qu’il supposerait qu’il s’agit d’une fonction externe, mais que cela a échoué. J’ai ensuite utilisé strtok_s et il a compilé! Ensuite, j’ai essayé sur Linux, mais maintenant, il se plaint de l’existence d’une “référence indéfinie à” strtok_s “”.

Est-ce qu’une fonction Windows uniquement et l’autre une fonction Linux? Que puis-je faire pour le comstackr sur les deux?

Ces deux fonctions sont vraiment laides, idiomes non intuitives pour l’parsing des chaînes, et ne parviennent généralement pas à répondre aux exigences de votre application particulière de manière subtile. Même plus pour le simple strtok en standard C. Il suffit de les jeter et d’écrire votre propre code pour parcourir le tableau de caractères et le décomposer au besoin. strchr , strspn et strcspn peuvent vous aider à faire cela ou vous pouvez simplement travailler à partir de zéro sur le tableau.

strtok_s est simplement la version Windows de strtok_r qui est standard partout ailleurs.

Un moyen (courant, je pense) de rendre un programme portable quand il s’agit de fonctions comme strtok_s / strtok_r est d’utiliser le préprocesseur:

 #if defined(_WIN32) || defined(_WIN64) /* We are on Windows */ # define strtok_r strtok_s #endif 

Comme les prototypes et les fonctionnalités sont les mêmes, vous ne pouvez désormais utiliser que strtok_r .

Je n’ai pas assez de réputation pour commenter les autres réponses, alors je vais devoir fournir les miennes.

Pour répondre à cette déclaration:

“strtok_s est une version sécurisée de strtok sous Windows avec saturation de mémoire tampon. Le strtok standard sur Windows est compatible avec les threads …”

Ce n’est pas vrai. strtok_s est la version sécurisée du thread pour le compilateur MSVC. Strtok n’est pas thread-safe!

Pour répondre à cette déclaration:

“Cela se briserait probablement si on compilait sur cygwin qui se présente sous la forme de fenêtres mais qui possède des interfaces de type POSIX comme strtok_r déjà définies.”

Encore une fois, pas vrai. La différence réside dans le compilateur que vous utilisez. Lorsque vous utilisez le compilateur Visual C ++ de Microsoft, MSVC, la fonction est strtok_s. Un autre compilateur, tel que GNU Comstackr Collection, GCC, peut utiliser une implémentation de bibliothèque standard différente telle que strtok_r. Pensez au compilateur, pas à la plate-forme cible, lors de l’identification de la fonction à utiliser.

À mon avis, la réponse de Joachim Pileborg est la meilleure de cette page. Cependant, il faut un petit assembly:

 #if defined(_WIN32) /* || defined(_WIN64) */ #define strtok_r strtok_s #endif 

_WIN32 et _WIN64 sont des macros prédéfinies fournies par le compilateur MSVC. _WIN64 est défini lors de la compilation d’une cible 64 bits. _WIN32 est défini pour les cibles 32 et 64 bits. Ceci est un compromis que Microsoft a fait pour la rétrocompatibilité. _WIN32 a été créé pour spécifier l’API Win32. Vous devez maintenant considérer _WIN32 pour spécifier l’API Windows – il n’est pas spécifique à une cible 32 bits.

strtok_r est une version thread-safe de strtok sur les systèmes POSIX

strtok_s est une version sécurisée de strtok sous Windows. Le strtok standard sur Windows est thread-safe, donc strtok_s devrait l’être.

Juste pour clarifier. strtok est thread-safe dans Windows. strtok utilise une variable TLS pour conserver le dernier pointeur de chaque thread. Cependant, vous ne pouvez pas utiliser strtok pour entrelacer l’access à plus d’une chaîne de jetons par thread. strtok_r et strtok_s traitent tous deux ce problème d’entrelacement en permettant à l’utilisateur de maintenir le contexte via le troisième paramètre. J’espère que cela t’aides.