Explíqueme el funcionamiento de la strtok()
función. El manual dice que rompe la cadena en fichas. No puedo entender del manual lo que realmente hace.
Agregué relojes str
y *pch
para verificar que funcionaba cuando ocurrió el primer ciclo while, el contenido de str
era solo "esto". ¿Cómo se imprimió en la pantalla el resultado que se muestra a continuación?
/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
Salida:
Dividiendo cadena "- Esto, una cadena de muestra". en tokens: Esta una muestra cuerda
strtok()
modifica su cadena de argumentos terminando los tokens con NUL antes de regresar. Si intenta examinar todo el búfer (str []) verá que se modifica entre las sucesivas llamadas astrtok()
.str
, relojstr[0]
,str[1]
,str[2]
, ...Respuestas:
strtok()
divide la cadena en tokens. es decir, comenzar desde cualquiera del delimitador hasta el siguiente sería su única ficha. En su caso, el token inicial será de "-" y terminará con el siguiente espacio "". Luego, el siguiente token comenzará con "" y terminará con ",". Aquí obtienes "Esto" como salida. De manera similar, el resto de la cadena se divide en fichas de espacio en espacio y finalmente termina la última ficha en "."fuente
la función de tiempo de ejecución de strtok funciona así
la primera vez que llama a strtok, proporciona una cadena que desea tokenizar
en el espacio de cadena anterior parece ser un buen delimitador entre palabras, así que usemos eso:
lo que sucede ahora es que se busca 's' hasta que se encuentra el carácter de espacio, se devuelve el primer token ('esto') yp apunta a ese token (cadena)
para obtener el siguiente token y continuar con la misma cadena, se pasa NULL como primer argumento ya que strtok mantiene un puntero estático a la cadena pasada anterior:
p ahora apunta a 'es'
y así sucesivamente hasta que no se puedan encontrar más espacios, entonces la última cadena se devuelve como la última 'cadena' del token.
más convenientemente, podría escribirlo así en su lugar para imprimir todos los tokens:
EDITAR:
Si desea almacenar los valores devueltos
strtok
, debe copiar el token a otro búfer, por ejemplo,strdup(p);
ya que la cadena original (señalada por el puntero estático en el interiorstrtok
) se modifica entre iteraciones para devolver el token.fuente
p
apunta a ese token" , es questrtok
debe mutar la cadena original colocando caracteres nulos en lugar de un delimitador (de lo contrario, otras funciones de cadena no sabrían dónde el token termina). Y también realiza un seguimiento del estado mediante una variable estática.strtok
mantiene una referencia interna estática que apunta al siguiente token disponible en la cadena; si le pasa un puntero NULL, funcionará desde esa referencia interna.Ésta es la razón por la
strtok
que no vuelve a entrar; tan pronto como le pasa un nuevo puntero, esa vieja referencia interna se golpea.fuente
strtok
no cambia el parámetro en sí (str
). Almacena ese puntero (en una variable estática local). A continuación, puede cambiar a qué apunta ese parámetro en llamadas posteriores sin que se devuelva el parámetro. (Y puede hacer avanzar ese puntero que ha mantenido sin embargo necesita realizar sus operaciones).Desde la
strtok
página POSIX :Existe una variante segura para subprocesos (
strtok_r
) que no hace este tipo de magia.fuente
ctime
devolver una cadena estática: práctica (nadie debe preguntarse quién debería liberarla), pero no reentrar y hacer tropezar si no está muy consciente de ello.strtok
no cambia el parámetro en sí (str
)".puts(str);
imprime "- Esto" desde que sestrtok
modificóstr
.La primera vez que lo llama, proporciona la cadena para tokenizar
strtok
. Y luego, para obtener los siguientes tokens, simplemente le daNULL
a esa función, siempre que devuelva un noNULL
puntero.La
strtok
función registra la cadena que proporcionó por primera vez cuando la llamó. (Lo que es realmente peligroso para aplicaciones multiproceso)fuente
strtok tokenizará una cadena, es decir, la convertirá en una serie de subcadenas.
Lo hace buscando delimitadores que separan estos tokens (o subcadenas). Y especificas los delimitadores. En su caso, quiere '' o ',' o '.' o '-' para ser el delimitador.
El modelo de programación para extraer estos tokens es que usted entregue su cadena principal y el conjunto de delimitadores. Luego lo llama repetidamente, y cada vez que strtok devolverá el siguiente token que encuentre. Hasta que llega al final de la cadena principal, cuando devuelve un valor nulo. Otra regla es que pasa la cadena solo la primera vez y NULL para las veces siguientes. Esta es una forma de decirle a strtok si está iniciando una nueva sesión de tokenización con una nueva cadena o si está recuperando tokens de una sesión de tokenización anterior. Tenga en cuenta que strtok recuerda su estado para la sesión de tokenización. Y por esta razón no es reentrante ni seguro para subprocesos (debería usar strtok_r en su lugar). Otra cosa que debe saber es que en realidad modifica la cadena original. Escribe '\ 0' para los delimitadores que encuentra.
Una forma de invocar strtok, de manera sucinta, es la siguiente:
Resultado:
fuente
strtok modifica su cadena de entrada. Coloca caracteres nulos ('\ 0') en él para que devuelva bits de la cadena original como tokens. De hecho, strtok no asigna memoria. Puede comprenderlo mejor si dibuja la cadena como una secuencia de cuadros.
fuente
Para comprender cómo
strtok()
funciona, primero es necesario saber qué es una variable estática . Este enlace lo explica bastante bien ...La clave para la operación de
strtok()
es preservar la ubicación del último separador entre llamadas seccesivas (es por eso questrtok()
continúa analizando la cadena muy original que se le pasa cuando se invoca con unanull pointer
en llamadas sucesivas).Eche un vistazo a mi propia
strtok()
implementación, llamadazStrtok()
, que tiene una funcionalidad ligeramente diferente a la proporcionada porstrtok()
Y aquí hay un ejemplo de uso
El código es de una biblioteca de procesamiento de cadenas que mantengo en Github , llamada zString. Eche un vistazo al código, o incluso contribuya :) https://github.com/fnoyanisi/zString
fuente
Así es como implementé strtok, no tan bueno, pero después de trabajar 2 horas finalmente funcionó. Soporta múltiples delimitadores.
fuente
strtok reemplaza los caracteres en el segundo argumento con un NULL y un carácter NULL también es el final de una cadena.
http://www.cplusplus.com/reference/clibrary/cstring/strtok/
fuente
Aquí está mi implementación que usa una tabla hash para el delimitador, lo que significa que O (n) en lugar de O (n ^ 2) (aquí hay un enlace al código) :
fuente
strtok () almacena el puntero en la variable estática donde lo dejó la última vez, por lo que en su segunda llamada, cuando pasamos el nulo, strtok () obtiene el puntero de la variable estática.
Si proporciona el mismo nombre de cadena, nuevamente comienza desde el principio.
Además, strtok () es destructivo, es decir, realiza cambios en la cadena original. así que asegúrese de tener siempre una copia del original.
Un problema más de usar strtok () es que, como almacena la dirección en variables estáticas, en la programación multiproceso, llamar a strtok () más de una vez provocará un error. Para esto use strtok_r ().
fuente
Para aquellos que todavía tienen dificultades para entender esta
strtok()
función, echen un vistazo a este ejemplo de pythontutor , es una gran herramienta para visualizar su código C (o C ++, Python ...).En caso de que el enlace se rompa, pegue:
Los créditos van para Anders K.
fuente
puede escanear la matriz de caracteres en busca del token si lo encontró, simplemente imprima una nueva línea o imprima el carácter.
fuente
Por lo tanto, este es un fragmento de código para ayudar a comprender mejor este tema.
Tokens de impresión
Tarea: Dada una oración, s, imprima cada palabra de la oración en una nueva línea.
Entrada:
How is that
Resultado:
Explicación: Entonces, aquí, se usa la función "strtok ()" y se itera usando el bucle for para imprimir los tokens en líneas separadas.
La función tomará parámetros como 'cadena' y 'punto de ruptura' y romperá la cadena en esos puntos de ruptura y formará tokens. Ahora, esos tokens se almacenan en 'p' y se usan más para imprimir.
fuente