funciona - strtok php
¿Cuál es la diferencia entre strtok_r y strtok_s en C? (5)
Ambas funciones son modismos realmente feos y poco intuitivos para analizar cadenas y, por lo general, no cumplen con los requisitos de su aplicación en particular de manera sutil. Incluso más para la estrategia simple en el estándar C. Simplemente tíralos y escribe tu propio código para iterar sobre la matriz de caracteres y dividirlo según sea necesario. strchr
, strspn
y strcspn
pueden ser útiles para hacer esto o simplemente puede trabajar desde cero en la matriz.
Estoy tratando de usar esta función en un programa de C que necesita poder compilar en Linux y Windows. Al principio intenté usar strtok_r, pero luego, cuando compilé en Windows, se quejó de que la función no existía y dijo que asumiría que es una función externa, pero luego falló. Luego utilicé strtok_s y compilé! Luego probé con Linux, pero ahora me quejo de que hay una "referencia indefinida a ''strtok_s''".
¿Es una función de Windows solamente y la otra una función de Linux? ¿Qué puedo hacer para que se compile en ambos?
No tengo suficiente reputación para comentar otras respuestas, así que tendré que proporcionar la mía.
Para abordar esta afirmación:
"strtok_s es una versión segura de desbordamiento de búfer de strtok en Windows. El estándar strtok en Windows es seguro para subprocesos ..."
Esto no es verdad. strtok_s es la versión segura para subprocesos para el compilador MSVC. ¡Strtok no es seguro para hilos!
Para abordar esta afirmación:
"Esto probablemente se rompería si se compilara en cygwin, que se informa a sí mismo como windows pero tiene interfaces posix como strtok_r ya definidas".
Una vez más, no es cierto. La diferencia es qué compilador usas. Cuando se utiliza el compilador de Visual C ++ de Microsoft, MSVC, la función es strtok_s. Otro compilador, como la colección de compiladores GNU, GCC, puede usar una implementación de biblioteca estándar diferente, como strtok_r. Piense en el compilador, no en la plataforma de destino, al identificar qué función utilizar.
En mi opinión, la respuesta de Joachim Pileborg es la mejor en esta página. Sin embargo, necesita una pequeña edición:
#if defined(_WIN32) /* || defined(_WIN64) */
#define strtok_r strtok_s
#endif
Tanto _WIN32 como _WIN64 son macros predefinidas proporcionadas por el compilador MSVC. _WIN64 se define al compilar un destino de 64 bits. _WIN32 está definido para objetivos de 32 y 64 bits. Este es un compromiso que Microsoft hizo para la compatibilidad con versiones anteriores. _WIN32 fue creado para especificar la API de Win32. Ahora debe considerar _WIN32 para especificar la API de Windows; no es específico de un destino de 32 bits.
Solo para aclarar. strtok es seguro para subprocesos en Windows. strtok usa una variable TLS para mantener el último puntero para cada hilo. Sin embargo, no puede usar strtok para intercalar el acceso a más de una cadena de token por hilo. strtok_r y strtok_s solucionan este problema de intercalación al permitir que el usuario mantenga el contexto a través del tercer parámetro. Espero que esto ayude.
strtok_r es una versión segura de subprocesos de strtok en sistemas POSIX
strtok_s es una versión segura de desbordamiento de búfer de strtok en Windows. El estándar strtok en windows es seguro para subprocesos, por lo que strtok_s debería serlo.
strtok_s
es simplemente la versión para Windows de strtok_r
que es estándar en todos los demás strtok_r
.
Una manera (en general, creo) de hacer que un programa sea portátil cuando se trata de funciones como strtok_s
/ strtok_r
es usar el preprocesador:
#if defined(_WIN32) || defined(_WIN64)
/* We are on Windows */
# define strtok_r strtok_s
#endif
Como los prototipos y la funcionalidad son los mismos, ahora solo puede usar strtok_r
.